threading 모듈

threading 모듈

  • 쓰레드란 하나의 프로세스 내에서 진행되는 하나의 실행 단위를 뜻한다.

  • 하나의 프로세스에서 여러 실행 단위가 실행되는 것을 멀티 쓰레드라 한다.

  • 프로세스쓰레드는 모두 프로그램을 수행한다는 공통점을 지니고 있지만,
    프로세스는 윈도우에서 여러 응용프로그램을 각각 실행시키는 것처럼 독립적으로 실행되어 독립된 메모리 공간을 사용하지만,
    멀티쓰레드하나의 프로세스내에서 여러 쓰레드가 프로세스 공간의 메모리공유해서 사용할 수 있다.


Thread.start()

  • 쓰레드를 시작할 때 사용한다.

Thread.run()

  • 쓰레드의 주요 동작을 정의한다.

Thread.join([timeout])

  • 쓰레드가 종료되기를 기다린다. [timeout]이 정의된 경우, 최대 정의된 시간만큼 기다린다.

Lock 객체

  • 하나의 프로세스에서 2개 이상의 쓰레드가 동시에 수행되는 경우, 쓰레드 간에 프로세스 공간의 메모리를 공유한다.

  • 만약 하나의 변수에 대해서 2개 이상의 쓰레드가 변경을 가하고자 한다면, 어떤 쓰레드가 먼저 수행되느냐에 따라 결과가 달라질 수 있다.

  • 이러한 상태를 경쟁 상태(Race condition)라고 한다.

  • 이러한 상황을 방지하기 위해서 파이썬에서는 Lock이라는 동기화 객체를 지원한다.

Lock객체는 locked와 unlocked의 2가지 상태를 가지며,

acquire()와 release()의 두 가지 함수만을 제공한다.

unlocked 상태에서 acquire()가 호출되면 locked 상태로 바뀌며,

locked 상태에서 release()가 호출되면 unlocked 상태로 바뀌게 된다.

locked 상태에서 다른 쓰레드가 acquire()를 호출하면

locked 상태의 쓰레드가 release()할 때까지 멈추게 된다.

다음 예제코드는 threading의 Thread와 Lock 객체를 이용해

각각 버그를 수정하는 시뮬레이션 프로그램이다.

전역 변수로 총 버그 개수를 정의해 놓고,

생성된 3개의 developer 쓰레드가

각각 0.1초에 하나씩 버그를 해결해 나가게 된다.

버그 개수가 0이 되어 모든 쓰레드가 종료되면 각자 몇 개씩

버그를 해결했는지를 출력한다.

from threading import Thread, Lock
# import thread
# import lock
import time

count = 10
lock = Lock()

class developer(Thread):
    def __init__(self,name):            # 초기화
        Thread.__init__(self)
        self.name = name
        self.fixed = 0

    def run(self):                      # 쓰레드 동작 정의
        global count
        while 1:
            lock.acquire()              # lock
            if count > 0 :
                count -= 1
                lock.release()          # unlock
                self.fixed += 1
                time.sleep(0.1)
            else :
                lock.release()          # unlock
                break


dev_list = []
for name in ['Shin', 'Woo', 'Choi']:
    dev = developer(name)               # thread 생성
    dev_list.append(dev)
    dev.start()                         # thread 시작
    

for dev in dev_list:
    dev.join()                          # wait
    print(dev.name, 'fixed', dev.fixed)




# 실행할 때마다 결과가 달라진다.

Shin fixed 3
Woo fixed 3
Choi fixed 4