Condition을 사용하여 두 개의 스레드가 번갈아 가며 실행하는 Python 예제 코드를 작성하기 위해 Claude 3.5 sonet과 ChatGPT 무료버전에게 질문해본 것을 정리했습니다.
글을 다 작성하고 나서 다시 읽어보니 똑같이 유료 버전의 모델을 사용해야 더 정확하지 않을까 싶네요
2025. 2. 2 최초작성
클로드와 쳇지피티에게 번갈아가며 물어본 결과 쓰레드 동기화를 AI도 어려워하는 구나 싶네요.
서로 상대방의 코드가 문제 있다고 얘기를 반복하며 수정하다가 최종적으로 쳇지피티가 수정한 코드를 클로드가 그렇게 작성해도 된다고 인정했어요.
마지막 쯤에 서로 주장을 반복하던 때에 답변 얻은 결과만 공유합니다.
Claude 3.5 sonet
notify_all()보다는 notify()가 더 적절합니다:
현재 상황에서는 항상 하나의 스레드만 대기 중이므로
notify_all()은 불필요하게 모든 대기 스레드를 깨움
ChatGPT 무료 버전
현재 코드에서는 condition.notify()를 사용하고 있습니다.
하지만 notify()는 기다리고 있는 스레드 중 하나만 깨우므로, 올바른 실행 순서를 보장하지 못할 가능성이 있습니다.
문제 상황
thread1()이 notify()를 호출했을 때, thread2()가 아닌 thread1()이 다시 깨어나는 경우가 생길 수 있음.
thread2()가 notify()를 호출했을 때도 thread1()이 아닌 다른 스레드가 깨어날 수도 있음.
이로 인해 thread1()과 thread2()가 번갈아 실행되지 않고 멈추거나 예기치 않은 실행 흐름이 발생할 가능성이 있음.
해결 방법:
✅ condition.notify() 대신 condition.notify_all()을 사용하여 모든 스레드를 깨운 후, while 조건에서 올바른 스레드만 실행되도록 한다.
최종 코드와 실행 결과입니다.
with에 condition을 적은 것은 클로드가 한 것이고 자기 차례가 아닐 경우 busy waiting하는 것은 쳇지피티가 추가 한 것입니다.
import threading def thread1(num): global number1, turn for i in range(num): with condition: # condition 객체를 사용하여 임계 영역 진입 while turn != 1: # 자기 차례가 아닐 경우 busy waiting condition.wait() print(f'[{number1}]', end=' ') number1 = number1 + 1 if number1 > 5: number1 = 0 turn = 2 # 다음 차례를 thread2로 변경 condition.notify_all() # 대기 중인 스레드를 모두 깨움 print('\nthread 1 exit') def thread2(num): global number2, turn for i in range(num): with condition: # condition 객체를 사용하여 임계 영역 진입 while turn != 2: # 자기 차례가 아닐 경우 busy waiting condition.wait() print(f'={number2}=', end=' ') number2 = number2 - 1 if number2 < 0: number2 = 5 turn = 1 # 다음 차례를 thread1로 변경 condition.notify_all() # 대기 중인 스레드를 모두 깨움 print('\nthread 2 exit') # 전역 변수 초기화 number1 = 0 # thread1이 사용할 변수, 0에서 시작 number2 = 5 # thread2가 사용할 변수, 5에서 시작 turn = 1 # thread1부터 시작하도록 설정 # 스레드 동기화를 위한 Condition 객체 생성 condition = threading.Condition() # 스레드 생성 t1 = threading.Thread(target=thread1, args=(13,)) t2 = threading.Thread(target=thread2, args=(13,)) # 스레드 시작 t1.start() t2.start() # 스레드 종료 대기 t1.join() t2.join() print('main exit') |
[0] =5= [1] =4= [2] =3= [3] =2= [4] =1= [5] =0= [0] =5= [1] =4= [2] =3= [3] =2= [4] =1= [5] =0= [0]
thread 1 exit
=5=
thread 2 exit
main exit
'Python > Python - 스레드&프로세스' 카테고리의 다른 글
Python Thread / Process 강제로 종료시키기 (0) | 2024.03.17 |
---|---|
Python Thread 예제 (0) | 2023.10.21 |
스레드가 죽었는지 확인하는 Python 예제 코드 (0) | 2023.10.14 |
Python에서 자식 Process 죽었는지 확인하는 예제 코드 (0) | 2023.10.12 |
Python에서 자식 Process ID 확인하는 예제 코드 (0) | 2023.10.12 |