Thread 사용에 있어서 임계영역의 필요성
아래와 같은 예제가 있습니다. 전역변수 account_balance 에 함수 안에서 더하고 빼는 과정을 하면서 최종적으로는 0이 되는 상태를 유지합니다.
import time import threading account_balance = 0 def change_account_balance(delta): global account_balance account_balance -= delta print("+",threading.currentThread().getName(),account_balance) account_balance += delta print("-",threading.currentThread().getName(),account_balance) threads = [threading.Thread(target=change_account_balance, args=[3]) for i in range(10)] for thread in threads: thread.start() thread.join()
그러나 실제 실행해보면 10개의 thread가 서로 경쟁을 하면서 전역 변수값을 수정하게 됩니다.
+ Thread-1 -3 - Thread-1 0 + Thread-2 -3 + Thread-3 -6 - Thread-2 -3 - Thread-3 -3 + Thread-5 -6 + Thread-4 -6 - Thread-5 -6 + Thread-7 -9 + Thread-6 -9 - Thread-4 -6 - Thread-7 -9 + Thread-10 -12 + Thread-9 -12 - Thread-6 -9 + Thread-8 -9 - Thread-10 -6 - Thread-8 0
임계 영역을 설정하는 방법
1. lock변수를 정의하고 threading.Lock()
2. with 키워드를 사용하거나 acquire() 메소드를 사용합니다.
첫번째 방법(with 키워드 사용)
import time import threading account_balance = 0 account_balance_lock = threading.Lock() def change_account_balance_sf1(delta): global account_balance with account_balance_lock: account_balance -= delta print("+",threading.currentThread().getName(),account_balance) account_balance += delta print("-",threading.currentThread().getName(),account_balance) threads = [threading.Thread(target=change_account_balance_sf1, args=[3]) for i in range(10)] for thread in threads: thread.start() thread.join()
결과
+ Thread-1 -3 - Thread-1 0 + Thread-2 -3 - Thread-2 0 + Thread-3 -3 - Thread-3 0 + Thread-4 -3 - Thread-4 0 + Thread-5 -3 - Thread-5 0 + Thread-6 -3 - Thread-6 0 + Thread-7 -3 - Thread-7 0 + Thread-8 -3 - Thread-8 0 + Thread-9 -3 - Thread-9 0 + Thread-10 -3 - Thread-10 0
두번째 방법(acquire() 메소드를 사용)
import time import threading account_balance = 0 account_balance_lock = threading.Lock() def change_account_balance_sf2(delta): global account_balance account_balance_lock.acquire() account_balance -= delta print("+",threading.currentThread().getName(),account_balance) account_balance += delta print("-",threading.currentThread().getName(),account_balance) account_balance_lock.release() threads = [threading.Thread(target=change_account_balance_sf2, args=[3]) for i in range(10)] for thread in threads: thread.start() thread.join()
결과
+ Thread-1 -3 - Thread-1 0 + Thread-2 -3 - Thread-2 0 + Thread-3 -3 - Thread-3 0 + Thread-4 -3 - Thread-4 0 + Thread-5 -3 - Thread-5 0 + Thread-6 -3 - Thread-6 0 + Thread-7 -3 - Thread-7 0 + Thread-8 -3 - Thread-8 0 + Thread-9 -3 - Thread-9 0 + Thread-10 -3 - Thread-10 0
댓글 없음:
댓글 쓰기