여러 스레드를 실행하는 것은 여러 다른 프로그램을 동시에 실행하는 것과 유사하지만 다음과 같은 이점이 있습니다.
- 프로세스 내의 여러 스레드는 메인 스레드와 동일한 데이터 공간을 공유하므로 별도의 프로세스일 때보다 더 쉽게 정보를 공유하거나 서로 통신할 수 있습니다.
- 스레드는 경량 프로세스라고도 하며 많은 메모리 오버헤드를 필요로 하지 않습니다. 프로세스보다 저렴합니다.
스레드에는 시작, 실행 순서 및 결론이 있습니다. 컨텍스트 내에서 현재 실행 중인 위치를 추적하는 명령 포인터가 있습니다.
- 선점 가능(중단)
- 다른 스레드가 실행되는 동안 일시적으로 보류(잠자기라고도 함)될 수 있습니다. 이를 항복이라고 합니다.
새 스레드 시작
다른 스레드를 생성하려면 스레드 모듈 에서 사용할 수 있는 다음 메서드를 호출해야 합니다.
thread.start_new_thread ( function, args[, kwargs] )
이 메서드 호출을 사용하면 Linux와 Windows 모두에서 새 스레드를 빠르고 효율적으로 생성할 수 있습니다.
메서드 호출이 즉시 반환되고 자식 스레드가 시작되고 전달된 args 목록으로 function을 호출합니다 . 함수가 반환되면 스레드가 종료됩니다.
여기서 args 는 인수 튜플입니다. 인수를 전달하지 않고 함수를 호출하려면 빈 튜플을 사용하십시오. kwargs 는 키워드 인수의 선택적 사전입니다.
#!/usr/bin/python
import thread
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# Create two threads as follows
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"
while 1:
pass
위의 코드가 실행되면 다음과 같은 결과가 생성됩니다.
Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009
저수준 스레딩에는 매우 효과적이지만 스레드 모듈은 최신 스레딩 모듈에 비해 매우 제한적입니다.
스레딩 모듈
Python 2.4에 포함된 새로운 스레딩 모듈은 이전 섹션에서 논의한 스레드 모듈보다 훨씬 강력하고 높은 수준의 스레드 지원을 제공합니다.
스레딩 모듈은 모든 방법 노출 스레드 모듈과 몇 가지 추가 방법을 제공합니다 -
- threading.activeCount() - 활성 상태인 스레드 개체의 수를 반환합니다.
- threading.currentThread() - 호출자의 스레드 컨트롤에 있는 스레드 개체의 수를 반환합니다.
- threading.enumerate() - 현재 활성화된 모든 스레드 개체의 목록을 반환합니다.
메서드 외에도 스레딩 모듈에는 스레딩을 구현 하는 Thread 클래스가 있습니다. Thread 클래스에서 제공하는 메소드 는 다음과 같습니다.
- run() - run() 메서드는 스레드의 진입점입니다.
- start() - start() 메서드는 run 메서드를 호출하여 스레드를 시작합니다.
- join([time]) - join()은 스레드가 종료될 때까지 기다립니다.
- isAlive() - isAlive() 메서드는 스레드가 여전히 실행 중인지 여부를 확인합니다.
- getName() - getName() 메서드는 스레드의 이름을 반환합니다.
- setName() - setName() 메서드는 스레드의 이름을 설정합니다.
스레딩 모듈을 사용하여 스레드 생성
스레딩 모듈을 사용하여 새 스레드를 구현하려면 다음을 수행해야 합니다.
- Thread 클래스 의 새 하위 클래스를 정의합니다 .
- 추가 인수를 추가 하려면 __init__(self [,args]) 메서드를 재정의합니다 .
- 그런 다음 run(self [,args]) 메서드를 재정의하여 스레드가 시작될 때 수행해야 하는 작업을 구현합니다.
새 만든 후에 스레드 서브 클래스를, 당신은 그것의 인스턴스를 생성하고 호출하여 새 스레드를 시작할 수 있습니다.
start() 차례로 run() 실행 방법.
#!/usr/bin/python
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print "Starting " + self.name
print_time(self.name, 5, self.counter)
print "Exiting " + self.name
def print_time(threadName, counter, delay):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
print "Exiting Main Thread"
위의 코드가 실행되면 다음과 같은 결과가 생성됩니다.
Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2
스레드 동기화
Python과 함께 제공되는 스레딩 모듈에는 스레드를 동기화할 수 있는 구현하기 쉬운 잠금 메커니즘이 포함되어 있습니다. 새 잠금 을 반환하는 Lock() 메서드 를 호출하여 새 잠금이 생성됩니다 .
새 잠금 개체 의 획득(차단) 메서드는 스레드가 동기적으로 실행되도록 하는 데 사용됩니다. 선택적 차단 매개변수를 사용하면 스레드가 잠금을 획득하기 위해 대기하는지 여부를 제어할 수 있습니다.
경우 차단이 0으로 설정되어, 0 값 스레드 즉시 반환은 잠금을 취득 할 수없는 경우에 잠금을 인수 한 경우 1. 차단이 1로 설정되면 스레드가 차단되고 잠금이 해제될 때까지 기다립니다.
새 잠금 개체 의 release() 메서드는 더 이상 필요하지 않을 때 잠금을 해제하는 데 사용됩니다.
#!/usr/bin/python
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print "Starting " + self.name
# Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
threadLock = threading.Lock()
threads = []
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
# Add threads to thread list
threads.append(thread1)
threads.append(thread2)
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
위의 코드가 실행되면 다음과 같은 결과가 생성됩니다.
Starting Thread-1
Starting Thread-2
Thread-1: Thu Mar 21 09:11:28 2013
Thread-1: Thu Mar 21 09:11:29 2013
Thread-1: Thu Mar 21 09:11:30 2013
Thread-2: Thu Mar 21 09:11:32 2013
Thread-2: Thu Mar 21 09:11:34 2013
Thread-2: Thu Mar 21 09:11:36 2013
Exiting Main Thread
다중 스레드 우선 순위 대기열
Queue 모듈은 항목의 특정 번호를 보유 할 수있는 새로운 큐 개체를 만들 수 있습니다. Queue를 제어하는 방법은 다음과 같습니다.
- get() - get()은 대기열에서 항목을 제거하고 반환합니다.
- put() - put은 항목을 큐에 추가합니다.
- qsize() - qsize()는 현재 대기열에 있는 항목 수를 반환합니다.
- empty() - empty()는 대기열이 비어 있으면 True를 반환합니다. 그렇지 않으면 거짓.
- full() - full()은 대기열이 가득 차면 True를 반환합니다. 그렇지 않으면 거짓.
#!/usr/bin/python
import Queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
결과
Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread
댓글