멀티태스킹은 여러 작업을 동시에 실행하는 것입니다.
멀티태스킹 유형은 다음과 같습니다.
1. 프로세스 기반 멀티태스킹:
모든 작업이 단일 프로세서에서 실행되는 동시에 여러 작업을 실행하는 것이 프로세스 기반 멀티태스킹입니다. 예를 들어, 이력서를 입력하고, 인터넷을 통해 영화를 다운로드하고, 같은 컴퓨터에서 동시에 노래를 들을 수 있습니다. 이것은 작업을 동시에 독립적으로 실행하는 예입니다. OS 레벨에 가장 적합합니다.
2. 스레드 기반 멀티태스킹:
모든 작업이 동일한 프로그램의 개별 부분인 시간에 다양한 작업을 실행하는 것을 스레드 기반 멀티태스킹이라고 하고 모든 개별 부분을 스레드라고 합니다. 프로그래밍 수준에서 가장 적합합니다.
여러 개의 독립적인 작업을 동시에 실행해야 하는 경우 멀티스레딩이 선호됩니다. 스레드 배포에 선호되는 Python에서 지원하는 "threading"이라는 내장 모듈이 있습니다. 모든 Python 프로그램에서 사용할 수 있는 메인 스레드가 있습니다. 프로그래밍 수준에서 가장 적합합니다.
다음 스크립트는 현재 처리중인 스레드의 이름을 출력하는 예제입니다.
import threading
print("Current Executing Thread:", threading.current_thread().getName())
Output:
Current Executing Thread: MainThread
스레드를 생성하는 방법
1. 클래스를 사용하지 않고 스레드 생성
프로그램에서 여러 스레드를 사용할 경우 실행 순서를 예측할 수 없으므로 다중 스레드 프로그램의 정확한 출력을 예측할 수 없습니다. 따라서 동일한 프로그램에 대해 정확한 출력을 제공할 수 없습니다.
from threading import *
def func():
for i in range(1, 5):
print("Child Thread Part")
t = Thread(target = func)
t.start()
for i in range(1, 5):
print("Main Thread Part")
Output:
Child Thread PartMain Thread Part
Main Thread Part
Main Thread Part
Main Thread Part
Child Thread Part
Child Thread Part
Child Thread Part
2. 스레드 클래스를 확장하여 스레드 생성
스레드 클래스에 대한 자식 클래스를 만들어야 합니다. 자식 클래스에서 run() 메서드는 필요한 작업을 재정의해야 합니다. start() 메서드를 호출하면 run() 메서드가 자동으로 실행되고 필요한 작업을 수행합니다.
from threading import *
class user_class(Thread): # Thread 클래스 상속
def run(self):
for i in range(1, 5):
print("Child Thread Part")
t = user_class()
t.start()
for i in range(1, 5):
print("Main Thread Part")
Output:
Child Thread PartMain Thread Part
Main Thread Part
Main Thread Part
Main Thread Part
Child Thread Part
Child Thread Part
Child Thread Part
3. 스레드 클래스로 확장하지 않고 스레드 생성
from threading import *
class user_class:
def func(self):
for i in range(1, 5):
print("Child Thread Part")
a = user_class()
t = Thread(target = a.func)
t.start()
for i in range(1, 5):
print("Main Thread Part")
Output:
Child Thread PartMain Thread Part
Main Thread Part
Main Thread Part
Main Thread Part
Child Thread Part
Child Thread Part
Child Thread Part
다음 스크립트는 멀티 스레딩 없이 두 함수를 호출해서 결과를 출력하고 시간을 측정한 예제입니다.
from threading import *
import time
def func1(n):
for i in n:
time.sleep(1)
print("Double:", 2*i)
def func2(n):
for i in n:
time.sleep(1)
print("Square:", i*i)
n = [2, 4]
begin_time = time.time()
func1(n)
func2(n)
print("Total time:", time.time()-begin_time)
Output:
Double: 4
Double: 8
Square: 4
Square: 16
Total time: 4.006982088088989
다음 스크립트는 멀티 스레딩을 사용하여 두 함수를 호출해서 결과를 출력하고 시간을 측정한 예제입니다.
from threading import *
import time
def func1(n):
for i in n:
time.sleep(1)
print("Double:", 2*i)
def func2(n):
for i in n:
time.sleep(1)
print("Square:", i*i)
n = [2, 4]
begin_time = time.time()
t1 = Thread(target = func1, args = (n,))
t2 = Thread(target = func2, args = (n,))
t1.start()
t2.start()
t1.join()
t2.join()
print("Total time:", time.time()-begin_time)
Output:
Double: 4
Square: 4
Double: Square: 16
8
Total time: 2.0042953491210938
스레드 이름 설정 및 가져오기
Python에서 모든 스레드에는 이름이 있습니다. 이름은 PVM(Parallel Virtual Machine)에 의해 생성된 기본 이름이거나 프로그래머가 할당한 사용자 정의 이름일 수 있습니다. 스레드 이름을 가져오고 설정하는 데 다음 방법이 사용됩니다.
t.getName(): 스레드의 이름이 반환됩니다.
t.setName(): 사용자 정의 이름이 설정됩니다.
다음 스크립트는 스레드 이름을 출력하고 설정하는 예제입니다.
from threading import *
print(current_thread().getName())
current_thread().setName("UserName")
print(current_thread().getName())
print(current_thread().name)
Output:
MainThread
UserName
UserName
스레드 식별 번호
고유 식별 번호는 Python에서 제공합니다. 이 식별 번호는 암시적 변수 "ident"로 액세스할 수 있습니다.
from threading import *
def func():
print("Child Thread Part\n")
t = Thread(target = func)
t.start()
print("Main Thread Identification Number:", current_thread().ident)
print("Child Thread Identification Number:", t.ident)
Output:
Child Thread Part
Main Thread Identification Number: 139818129758080
Child Thread Identification Number: 139817633142528
Active_count() 함수
현재 실행 중인 활성 스레드 수를 반환합니다.
from threading import *
import time
def func():
print(current_thread().getName(), " start")
time.sleep(3)
print(current_thread().getName(), " end")
print("Active Thread:", active_count())
t1 = Thread(target = func, name = "ChildThread-1")
t2 = Thread(target = func, name = "ChildThread-2")
t1.start()
t2.start()
print("Active Thread:", active_count())
time.sleep(5)
print("Active Thread:", active_count())
Output:
ChildThread-1ChildThread-2 start
Active Thread: 12
start
ChildThread-2 end
Active Thread: 12
ChildThread-1 end
Active Thread: 11
Active Thread: 10
열거 기능
현재 실행 중인 모든 활성 스레드 목록을 생성합니다. 종료된 스레드나 아직 시작되지 않은 스레드는 포함되지 않습니다.
from threading import *
import time
def func():
print(current_thread().getName(), "--> started")
time.sleep(3)
print(current_thread().getName(), "--> ended")
t1 = Thread(target = func, name = "ChildThread-1")
t2 = Thread(target = func, name = "ChildThread-2")
t1.start()
t2.start()
el = enumerate()
for e in el:
print("Thread Name:", e.name)
time.sleep(5)
el = enumerate()
for e in el:
print("Thread Name:", e.name)
Output:
ChildThread-1 --> started
ChildThread-2 --> started
Thread Name: UserName
Thread Name: Thread-2
Thread Name: Thread-3
Thread Name: Thread-1
Thread Name: pydevd.Writer
Thread Name: pydevd.Reader
Thread Name: pydevd.CommandThread
Thread Name: Thread-9
Thread Name: pydevd.CheckAliveThread
Thread Name: _colab_inspector_thread
Thread Name: ChildThread-1
Thread Name: ChildThread-2
ChildThread-1 --> endedChildThread-2
--> ended
Thread Name: UserName
Thread Name: Thread-2
Thread Name: Thread-3
Thread Name: Thread-1
Thread Name: pydevd.Writer
Thread Name: pydevd.Reader
Thread Name: pydevd.CommandThread
Thread Name: Thread-9
Thread Name: pydevd.CheckAliveThread
Thread Name: _colab_inspector_thread
IsAlive() 메서드
스레드 객체를 사용하여 지정된 스레드가 현재 실행 중인지 여부를 확인합니다. 스레드가 살아 있으면 True, 그렇지 않으면 False를 반환합니다.
from threading import *
import time
def func():
print(current_thread().getName(), "--> started")
time.sleep(3)
print(current_thread().getName(), "--> ended")
t1 = Thread(target = func, name = "ChildThread-1")
t2 = Thread(target = func, name = "ChildThread-2")
t1.start()
t2.start()
print(t1.name, "isAlive :", t1.isAlive())
print(t2.name, "isAlive :", t1.isAlive())
time.sleep(5)
print(t1.name, "isAlive :", t1.isAlive())
print(t2.name, "isAlive :", t1.isAlive())
Output:
ChildThread-1 --> started
ChildThread-2 --> started
ChildThread-1 isAlive : True
ChildThread-2 isAlive : True
ChildThread-1 --> ended
ChildThread-2 --> ended
ChildThread-1 isAlive : False
ChildThread-2 isAlive : False
Join() 메서드
스레드가 다른 스레드가 완료될 때까지 기다리려면 join() 메서드가 사용됩니다.
join() 메서드를 호출하면 주 스레드 객체가 종료될 때까지 호출 스레드가 차단됩니다. 스레드 개체는 다음 경우 중 하나에서 종료됩니다.
정상 종료
처리되지 않은 예외
선택적 타임아웃까지
따라서 join() 메서드는 메인 스레드 객체가 종료될 때까지 대기 상태를 보여줍니다. 시간 제한 값은 조인 방법과 관련하여 지정할 수도 있습니다. 몇 번이든 호출할 수 있습니다.
다음 스크립트는 메인 스레드가 자식 스레드 실행을 완료할 때까지 기다리는 예제입니다. 자식 스레드가 모두 수행될 때까지 기다렸다가 메인 스레드를 실행하였습니다.
from threading import *
import time
def func():
for i in range(5):
print("Child thread")
time.sleep(2)
t1 = Thread(target = func)
t1.start()
t1.join()
for i in range(3):
print("Main thread")
Output:
Child thread
Child thread
Child thread
Child thread
Child thread
Main thread
Main thread
Main thread
다음 스크립트는 메인 쓰레드가 join() 메소드에서 주어진 시간만큼 기다리는 예제입니다.
from threading import *
import time
def func():
for i in range(5):
print("Child thread")
time.sleep(2)
t1 = Thread(target = func)
t1.start()
t1.join(5)
for i in range(3):
print("Main thread")
Output:
Child thread
Child thread
Child thread
Main thread
Main thread
Main thread
데몬 스레드
데몬 스레드는 백그라운드에서 실행되는 스레드입니다. 기본적으로 GC(가비지 수집기)와 같은 데몬이 아닌 스레드에 대한 지원을 제공합니다. 메인 스레드가 메모리 부족에 직면하면 PVM은 즉시 가비지 수집기를 실행하여 쓸모 없는 개체를 제거하고 여유 메모리를 제공하므로 메인 스레드가 메모리 문제에 직면하지 않고 처리를 계속합니다.
스레드가 데몬 스레드인지 확인하려면 t.isDaemon()을 사용하면 됩니다.
from threading import *
print(current_thread().isDaemon())
print(current_thread().daemon)
'프로그래밍 언어 > 파이썬 (Python)' 카테고리의 다른 글
[파이썬 학습] 스레드 간 통신 (0) | 2022.02.27 |
---|---|
[파이썬 학습] 스레드 동기화 (0) | 2022.02.26 |
[파이썬 학습] 사용자 모듈 (0) | 2022.02.23 |
[파이썬 학습] Datetime, Math, Random 모듈 (0) | 2022.02.22 |
[파이썬 학습] 디버거 모듈과 컬렉션 모듈 (0) | 2022.02.20 |