이번에는 Event에 대해서 설명하도록 하겠습니다.
Event는 두개 이상의 thread가 한쪽의 작업이 끝났는지 기다리는 용도로 사용합니다. 만약 Event기능이 없다면 한쪽 thread에서는 특정 변수값이 변화가 생기는지 조건문을 이용해서 계속 검사 하도록 구현을 해야합니다. 이렇게 되면 CPU 자원을 소모하게 됩니다.
먼저 event 없이 구현했을때 아래와 같은 방식으로 구현됩니다.
import time import datetime import threading account_balance = 0 tevent = 0 def wait_for_event(): global tevent """Wait for the event to be set before doing anything""" print(datetime.datetime.now(),'wait_for_event: starting') while True: if tevent == 1: break print(datetime.datetime.now(),'wait_for_event: end') def change_account_balance(delta): wait_for_event() global account_balance account_balance -= delta print("+",threading.currentThread().getName(),account_balance) account_balance += delta print("-",threading.currentThread().getName(),account_balance) thread1 = threading.Thread(target=change_account_balance, args=(20,)) thread1.start() thread2 = threading.Thread(target=change_account_balance, args=(10,)) thread2.start() print(datetime.datetime.now(),"sleep") time.sleep(3) print(datetime.datetime.now(),"sleep out") tevent = 1 thread1.join() thread2.join()
동작 설명
main thread에서 3초 기다린 후(time.sleep(3)) thread를 동작 시키기 위한 코드 입니다.
전역 변수를 이용해서 값이 변경되기를 기다리게 됩니다. 이렇게 되면 CPU자원을 계속 소모하게 됩니다.
실행 화면
2020-08-23 08:26:49.402400 wait_for_event: starting 2020-08-23 08:26:49.411379 wait_for_event: starting 2020-08-23 08:26:49.423345 sleep 2020-08-23 08:26:52.460225 sleep out 2020-08-23 08:26:52.466207 wait_for_event: end + Thread-2 -10 2020-08-23 08:26:52.466207 wait_for_event: end - Thread-2 0 + Thread-1 -20 - Thread-1 0
아래는 Event 사용 예제입니다.
1. Event() 변수 정의
2. 기다리는 곳에서는 wait() 사용
3. 명령을 주는곳에서는 set() 사용
import time import datetime import threading account_balance = 0 account_balance_lock = threading.Lock() tevent = threading.Event() # wait() is_set() set() def wait_for_event(e): """Wait for the event to be set before doing anything""" print(datetime.datetime.now(),'wait_for_event: starting') e.wait() print(datetime.datetime.now(),'wait_for_event: e.is_set()->', e.is_set()) def wait_for_event_timeout(e, t): """Wait t seconds and then timeout""" print(datetime.datetime.now(),'wait_for_event_timeout: starting') e.wait(t) print(datetime.datetime.now(),'wait_for_event_timeout: e.is_set()->', e.is_set()) def change_account_balance(e, delta): wait_for_event_timeout(e,10) global account_balance account_balance -= delta print("+",threading.currentThread().getName(),account_balance) account_balance += delta print("-",threading.currentThread().getName(),account_balance) thread1 = threading.Thread(target=change_account_balance, args=(tevent,20)) thread1.start() thread2 = threading.Thread(target=change_account_balance, args=(tevent,10)) thread2.start() print(datetime.datetime.now(),"sleep") time.sleep(3) print(datetime.datetime.now(),"sleep out") tevent.set() thread1.join() thread2.join()
wait()함수 호출시 시간을 설정가능합니다.
실행화면
처음 예제와 거의 동일합니다.
2020-08-23 08:32:13.383186 wait_for_event_timeout: starting 2020-08-23 08:32:13.386177 wait_for_event_timeout: starting 2020-08-23 08:32:13.386177 sleep 2020-08-23 08:32:16.388159 sleep out 2020-08-23 08:32:16.388159 wait_for_event_timeout: e.is_set()-> True 2020-08-23 08:32:16.388159 wait_for_event_timeout: e.is_set()-> True + Thread-1 -20 + Thread-2 -30 - Thread-2 0 - Thread-1 -10
댓글 없음:
댓글 쓰기