파이썬(Python) Thread - 동기화 설명
지난 시간에 이어서 오늘은 파이썬 쓰레드 동기화에 대해서 간단하게 설명하겠습니다.
쓰레드는 보통 둘 이상의 실행 흐름을 가지고 있기 때문에 공통 메모리 영역의 값을 참조하는 과정에서
동일한 데이터를 조작하는 등의 일련의 과정이 일어나게 됩니다.
그 과정에서 문제가 일어날 가능성이 있는데 쓰레드의 실행 순서 조정 및 메모리 접근 제한 등으로
문제를 해결하게 되며, 이 때 쓰레드의 동기화 기법이 필요하게 됩니다.
문서 하단에서 간단하게 예제를 작성해보겠습니다.
Python 관련 포스팅 : Python 관련
Python 관련 포스팅 : Python 관련
파이썬(Python) Thread - 구조
보통 Thread는 아래와 아키텍처로 나타낼 수 있으며, 관련 예제는 하단에서 설명합니다.
Thread 구조 - 출처
파이썬(Python) Thread 동기화 - 예제 코드
파이썬 쓰레드 동기화를 구현하지 않은 예제와 동기화를 구현한 비교 예제 소스 입니다.
Threading-lock1.py
123456789101112131415161718192021 #Python Thread Synchronization(동기화) 예제1 import threading tot = 0 def add_total(amount): """ 쓰레드에서 실행 할 함수 전역변수 tot에 amount 더하기 """ global tot tot += amount print (threading.currentThread().getName()+' Not Synchronized :',tot) #동기화가 되어 있지 않은 쓰레드 예제if __name__ == '__main__': for i in range(10000): my_thread = threading.Thread( target=add_total, args=(1,)) my_thread.start()
- 5번 라인 : 각 쓰레드에서 참조 할 변수 선언
- 7번 라인 : 쓰레드로 실행할 add_total 함수 선언- 19번 라인 : add_total 함수 할당- 21번 라인 : start 메소드 호출
위의 예제는 동기화를 구현하지 않았으므로, 좋지 않은 예제 코드 입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #Python Thread Synchronization(동기화) 예제1 import threading tot = 0 def add_total(amount): """ 쓰레드에서 실행 할 함수 전역변수 tot에 amount 더하기 """ global tot tot += amount print (threading.currentThread().getName()+' Not Synchronized :',tot) #동기화가 되어 있지 않은 쓰레드 예제 if __name__ == '__main__': for i in range(10000): my_thread = threading.Thread( target=add_total, args=(1,)) my_thread.start() |
- 5번 라인 : 각 쓰레드에서 참조 할 변수 선언
- 7번 라인 : 쓰레드로 실행할 add_total 함수 선언
- 7번 라인 : 쓰레드로 실행할 add_total 함수 선언
- 19번 라인 : add_total 함수 할당
- 21번 라인 : start 메소드 호출
위의 예제는 동기화를 구현하지 않았으므로, 좋지 않은 예제 코드 입니다.
위의 예제는 동기화를 구현하지 않았으므로, 좋지 않은 예제 코드 입니다.
Threading-lock2.py
Threading-lock2.py
12345678910111213141516171819202122232425262728293031323334353637 #Python Thread Synchronization(동기화) 예제2 import threading tot = 0lock = threading.Lock() def add_total(amount): """ 쓰레드에서 실행 할 함수 전역변수 tot에 amount 더하기 """ global tot lock.acquire() try: tot += amount finally: lock.release() print (threading.currentThread().getName()+' Synchronized :',tot) """ 또는 global total with lock: total += amount print (threading.currentThread().getName()+' Synchronized :',tot) with 문으로 더 간단하게 사용 가능 """ #동기화가 되어 있는 쓰레드 예제if __name__ == '__main__': for i in range(10000): my_thread = threading.Thread( target=add_total, args=(1,)) my_thread.start()
- 6번 라인 : 각 쓰레드에서 참조 할 변수 선언
- 7번 라인 : 쓰레드 공유데이터 Lock 사용을 위해 객체 획득- 15번 라인 : acquire 메소드를 통해서 해당 블럭에 lock 사용- 19번 라인 : 공유 데이터 계산 완료 후 lock 해제
- 35번 라인 : add_total 함수 할당- 36번 라인 : start 메소드 호출
lock을 통해서 먼저 진입한 쓰레드가 작업을 완료 후 다른 쓰레드에 제어권을 넘기는 과정을 통해서
쓰레드의 동기화를 가능하게 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #Python Thread Synchronization(동기화) 예제2 import threading tot = 0 lock = threading.Lock() def add_total(amount): """ 쓰레드에서 실행 할 함수 전역변수 tot에 amount 더하기 """ global tot lock.acquire() try: tot += amount finally: lock.release() print (threading.currentThread().getName()+' Synchronized :',tot) """ 또는 global total with lock: total += amount print (threading.currentThread().getName()+' Synchronized :',tot) with 문으로 더 간단하게 사용 가능 """ #동기화가 되어 있는 쓰레드 예제 if __name__ == '__main__': for i in range(10000): my_thread = threading.Thread( target=add_total, args=(1,)) my_thread.start() |
- 6번 라인 : 각 쓰레드에서 참조 할 변수 선언
- 7번 라인 : 쓰레드 공유데이터 Lock 사용을 위해 객체 획득
- 7번 라인 : 쓰레드 공유데이터 Lock 사용을 위해 객체 획득
- 15번 라인 : acquire 메소드를 통해서 해당 블럭에 lock 사용
- 19번 라인 : 공유 데이터 계산 완료 후 lock 해제
- 35번 라인 : add_total 함수 할당
- 36번 라인 : start 메소드 호출
lock을 통해서 먼저 진입한 쓰레드가 작업을 완료 후 다른 쓰레드에 제어권을 넘기는 과정을 통해서
쓰레드의 동기화를 가능하게 한다.
lock을 통해서 먼저 진입한 쓰레드가 작업을 완료 후 다른 쓰레드에 제어권을 넘기는 과정을 통해서
쓰레드의 동기화를 가능하게 한다.
Python Thread 의 추가적인 상세 설명은 이 곳을 참고해 주세요.
Python Thread 의 추가적인 상세 설명은 이 곳을 참고해 주세요.
파이썬(Python) Thread 동기화 - 예제 실행 화면
아래 두 개의 이미지로 실제 실행 화면을 확인하실 수 있습니다.
실제 실행 화면1
실제 실행 화면2
마무리
이번 포스팅에서는 파이썬 쓰레드 동기화를 구현하는 방법을 간단하게 설명했습니다.
다음 시간에는 쓰레드의 데이터 전달 방법에 대해서 포스팅을 하겠습니다.
소스코드 다운로드 : python_thread(2).zip
'언어 > Python' 카테고리의 다른 글
파이썬(Python) - Thread(쓰레드) 설명 및 예제 소스 코드(4) - 일정 주기 반복 실행 (2) | 2018.05.25 |
---|---|
파이썬(Python) - Thread(쓰레드) 설명 및 예제 소스 코드(3) - 데이터 통신 (4) | 2018.05.12 |
파이썬(Python) - Thread(쓰레드) 설명 및 예제 소스 코드(1) - 기초 (1) | 2018.05.06 |
파이썬(Python) - 제네레이터(Generator) 설명 및 예제 소스 코드 (0) | 2018.05.04 |
파이썬(Python) - 이터레이터(Iterator) 설명 및 예제 소스 코드 (0) | 2018.04.27 |