- 본 포스팅을 읽기 전에, 이전 포스팅 26.스레드 동기화를 먼저 읽는 것을 권장합니다.
1. 스레드 동기화 이슈의 원인
# 파이썬 코드입니다.
import threading
g_count = 0
def thread_main():
global g_count
for i in range(10000):
g_count = g_count + 1
threads = []
for i in range(50):
th = threading.Thread(target=thread_main)
threads.append(th)
for th in threads:
th.start()
for th in threads:
th.join()
print('g_count = ', g_count)
- 이전 포스팅에서 위의 코드를 이용해 스레드 동기화 이슈를 확인했다.
- 발생한 스레드 동기화 이슈의 원인은 연산이 누락된다는 것이다.
- 그렇다면 이 문제를 어떻게 해결할 수 있을까?
a) Mutual Exclusion
- 연산 누락이 발생하는 부분은 공유되는 데이터를 참조하는 부분에서 발생한다.
- 각 쓰레드가 갖고있는 PC, SP 값이 다르기 때문에 발생하는 문제로 이 부분을 동기화 해주면 된다.
- 그렇다면 정확하게 무엇을 해야할까?
def thread_main():
global g_count
for i in range(100000):
g_count = g_count + 1
- 공유되는 데이터를 연산하는 과정에서 누락이 발생한다. 그렇다면 위의 코드부분이 문제가 발생하는 부분이다.
- 한 쓰레드가 연산을 완료할 때까지 다른 쓰레드는 같은 함수를 사용하지 못하게 하여 문제를 해결할 수 있다.
- 일종의 잠금(lock)을 걸어놓는 것이다.
# 파이썬 코드입니다.
import threading
g_count = 0
def thread_main():
global g_count
lock.acquire() #2 좌물쇠 잠금을 요청 (요청한 스레드가 좌물쇠 열쇠를 갖고있음)
for i in range(100000):
g_count = g_count + 1
lock.release() #3 좌물쇠 해제 (다른 스레드가 좌물쇠를 사용할 수 있음)
lock = threading.Lock() #1 좌물쇠 생성
threads = []
for i in range(50):
th = threading.Thread(target=thread_main)
threads.append(th)
for th in threads:
th.start()
for th in threads:
th.join()
print('g_count = ', g_count)
2. 결과확인
- 직접 코드를 실행해보면 알겠지만, 이전에 작성한(동기화 이슈가 발생한) 코드보다 실행속도가 현저히 떨어진다.
- 그 이유는 스레드가 thread_main() 함수를 순차적으로 사용하도록 만들었기 때문이다.
- 위의 첨부 사진처럼, 몇번을 시도해도 정확한 값이 출력되는 것을 알 수 있다.
- 이 방법 외에도 스레드 동기화 이슈를 해결하는 방법들이 있으니 찾아보기를 바란다.
'컴퓨터공학기초 개념 > 운영체제' 카테고리의 다른 글
29. 스레드(Thread) - 교착(Deadlock)과 기아(Starvation)상태 (0) | 2021.07.05 |
---|---|
28. 스레드(Thread) - 세마포어(Semaphore) (0) | 2021.07.05 |
26. 스레드(Thread) - 동기화(Synchronization) (0) | 2021.05.11 |
25. 스레드의 장단점 (0) | 2021.05.04 |
24. 스레드란? (thread 개념) (0) | 2021.04.29 |
댓글