본문 바로가기
컴퓨터공학기초 개념/운영체제

27. 스레드 동기화 이슈 해결방법

by devraphy 2021. 5. 11.

- 본 포스팅을 읽기 전에, 이전 포스팅 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() 함수를 순차적으로 사용하도록 만들었기 때문이다.
  • 위의 첨부 사진처럼, 몇번을 시도해도 정확한 값이 출력되는 것을 알 수 있다.  
  • 이 방법 외에도 스레드 동기화 이슈를 해결하는 방법들이 있으니 찾아보기를 바란다.

댓글