IT개발/Python(파이썬)2010. 8. 26. 18:22
■Threading 모듈

멀티쓰레딩 프로그램을 하기 위해서는 thread 모듈보다는 threading 모듈을 사용하는 것이 좋다. threading 모듈이 더 다양한 기능을 지원한다.
Thread 객체를 이용해서 쓰레드를 생성하는 방법은 두가지가 있다.

첫째, 호출가능한 객체(함수)를 생성자에 직접 전달하는 방법
둘째, 서브클래스에서 run 메소드를 구현


1. 생성자에서 직접 함수를 전달하는 방법
import threading, time

# 쓰레드로 실행될  함수를 정의
def myThread(id):
        for i in range(10):
                print 'id %s --> count : %d' % (id, i)
                time.sleep(0)           # Thread 종료

threads = []                             # 쓰레드 객체를 저장하는 리스트 (쓰레드 관리 리스트)

for i in range(2):
        th = threading.Thread(target=myThread, args=(i,))
        th.start()                          # 쓰레드 시작
        threads.append(th)           # thread 객체를 리스트에 저장

for th in threads:
        th.join()                          # 각 쓰레드가 종료될때까지 대기
print 'Finish all threads'

(실행결과)
[citylock@nmsfile thread]$ ./threadingGenerationONE.py
id 0 --> count : 0
id 0 --> count : 1
id 0 --> count : 2
id 0 --> count : 3
id 0 --> count : 4
id 0 --> count : 5
id 0 --> count : 6
id 0 --> count : 7
id 0 --> count : 8
id 0 --> count : 9
id 1 --> count : 0
id 1 --> count : 1
id 1 --> count : 2
id 1 --> count : 3
id 1 --> count : 4
id 1 --> count : 5
id 1 --> count : 6
id 1 --> count : 7
id 1 --> count : 8
id 1 --> count : 9
Finish all threads

2. 서브클래스에서 run 메소드 구현
import threading, time

# Thread의 서브 클래스
class MyThread(threading.Thread):
        def run(self):            # run 메소드는 쓰레드가 실행할 코드를 가진다.
                for i in range(10):
                        print 'id %s --> count:%d' % (self.getName(), i)
                        # getName()는 쓰레드의 이름을 알려준다.
                        time.sleep(0)

threads = []            # 쓰레드를 관리하는 리스트

for i in range(2):
        th = MyThread()     # 쓰레드 객체 생성
        th.start()          # 쓰레드 시작
        threads.append(th)  # thread 객체를 리스트에 저장

for th in threads:
        th.join()             # 쓰레드기 끝날때까지 대기
print 'Finish all threads'


(실행결과)
[citylock@nmsfile thread]$ ./threadingGenerationTwo.py
id Thread-1 --> count:0
id Thread-1 --> count:1
id Thread-1 --> count:2
id Thread-1 --> count:3
id Thread-1 --> count:4
id Thread-1 --> count:5
id Thread-1 --> count:6
id Thread-1 --> count:7
id Thread-1 --> count:8
id Thread-1 --> count:9
id Thread-2 --> count:0
id Thread-2 --> count:1
id Thread-2 --> count:2
id Thread-2 --> count:3
id Thread-2 --> count:4
id Thread-2 --> count:5
id Thread-2 --> count:6
id Thread-2 --> count:7
id Thread-2 --> count:8
id Thread-2 --> count:9
Finish all threads

3. Lock, RLock 객체

Lock 객체는 thread 모듈의 allocate_lock()와 같이 변수를 락, 해제 하는 기능을 제공한다.
RLock 객체는 기본적으로 Lock 객체와 동일하나 락을 소유하고 있는 쓰레드가 여려개의 acquire(), release()를 호출할수 있다.

예제)
# description :
#   Lock 객체는 락과 해제 기능을 제공한다.
import threading

g_count = 0

class MyThread(threading.Thread):
        def run(self):
                global g_count
                for i in range(10):
                        lock.acquire()        # 락을 얻고
                        g_count += 1
                        lock.release()        # 락을 해제

lock = threading.Lock()                  
threads = []

for i in range(10):                             # 쓰레드 객체 10 개 생성
        th = MyThread()
        th.start()
        threads.append(th)

for th in threads:                              # 10 개의 쓰레드가 모두 종료되기를 대기
        th.join()

print 'Finish all threads : ', g_count

 
4. Condition 객체

쓰레드 Condition 객체를 하기 위해서는 Thread status 에 대해서 확인해 보면 다음과 같다. 조건 변수(Condition Variable)에 하나의 쓰레드 대기큐(Waiting Queue)를 가지고 있고, wait()를 호출하는 쓰레드는 대기큐로 들어간다. 다른 쓰레드에서 notify()를 호충해 주면 대기큐에 있는 하나의 쓰레드를 깨워서 블락큐(Block Queue)에 넣고 락이 해제되기를 기다린다.

위와 같이 쓰레드를 관리하기 위해서 Condition 객체가 이용된다.



cv = threading.Condition()

1. wait()  호출하는 쓰레드

cv.acquire()              # 쓰레드에 락을 얻는다
...  (쓰레드에서 하는 작업 수행)

     cv.wait()             # 락을 해제하고, cv의 대기 큐에서 기다린다.

... ( 대기큐에서 나온후 작업)

cv.release()

2. 다른 쓰레드에서 notify()로 대기하는 쓰레드를 해제

cv.acquire()              # 쓰레드에 락을 얻는다
...  (쓰레드에서 하는 작업 수행)

     cv.notify()             # cv의 대기큐에 있는 쓰레드 하나를 깨워준다. 

... ( 나머지 작업 수행)
cv.release()
















Posted by 시티락