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

26. 스레드(Thread) - 동기화(Synchronization)

by devraphy 2021. 5. 11.

1. 동기화 이슈란?

- 다수의 프로세스 또는 다수의 쓰레드가 하나의 데이터에 대한 동시접근 및 사용으로 인해 발생하는 문제를 의미한다. 

- 아래의 예시를 참고하자. 

 

  • 한 프로세스 내부에 스레드 A, B, C가 있다.
  • 스레드 A, B, C가 공유하는 example 이라는 변수(= 데이터)가 있다.
  • 스레드 A, B, C는 example의 값을 변경하는 연산을 수행한다. 
  • 스레드 A, B, C는 example의 값을 계속해서 변경시키고 동시에 참조하는 과정을 반복하게 된다.
  • 그 결과, 연산 누락이 발생하여 비정상적인 결과값이 나온다.

- 이와 같은 현상을 스레드의 동기화 이슈/문제 라고 부른다.  

 

 


2. 예제 코드를 통한 스레드 동기화 이슈의 이해

a) 예제 코드

# 파이썬 코드입니다. 

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)

 

 

b) 예제코드 설명

1. thread_main() 

  • 스레드 내부에서 수행할 연산을 정의한 함수
  • g_count 변수에 1씩 더하는 연산을 1000번 수행한다. 

 

2. threads = []

  • 생성된 스레드를 담을 리스트

 

3. th = threading.Thread(target = thread_main) 

  • 스레드를 생성하는 함수
  • target이라는 매개변수에는 스레드가 수행할 연산이 정의된 함수를 넣어준다. 

 

4. th.start() 

  • 스레드를 실행하는 함수 

 

5. th.join() 

  • 스레드 실행이 완료(=종료)되었음을 확인하는 함수 
  • 다시 말해, 스레드가 종료될 때까지 기다리는 함수다. 

 

c) 예상 결과

  • 하나의 쓰레드가 실행될 때마다 g_count의 값은 10,000씩 증가한다. 
  • 쓰레드를 50개 생성하고 실행하기 때문에 g_count의 값은 10,000*50인 500,000이 되어야 한다. 
  • thread_main() 함수 안의 for문의 반복 회수를 a라고 하면, g_count의 결과값은 a*50이 나와야 하는 것이다. 

 


3. 결과 확인

- thread_main() 함수 안의 for문의 반복 회수를 a라고 하자

 

a) a = 10,000인 경우

- 예상처럼 잘 나온다. 그렇다면 숫자를 더 키워보자. 

 

b) a = 100,000인 경우

- 4번 모두 다른 값을 출력한다. 

- 예상대로라면 50 * 100,000인 5,000,000을 결과값으로 출력해야한다. 

- 이렇게 결과값이 계속해서 변동되는 이유는 스레드의 동기화 이슈 때문이다. 

댓글