스레드에서 발생하는 동기화 이슈에 대해서 알아보자.
다음과 같이 스레드 A, B, C가 있다고 가정해보자.
스레드 실행 순서 역시 스케쥴러가 관리하기 때문에 실행 순서가 유동적으로 바뀐다.
이에 따라서, 하나의 스레드에서 변수 값을 바꿔서 다른 스레드에서 사용하다가, 또 다른 스레드에서 변수 값을 바꿔 다른 스레드들이 사용하는 상황이 발생한다.
이를 동기화(Synchronization) 이슈라고 부르고 이러한 이슈로 스레드의 관리가 필요하다.
대부분의 동기화 이슈는 컨텍스트 스위칭에서 실행되어야할 함수가 누락되면서 발생한다.
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) # 50개의 스레드 생성
for th in threads:
th.start() # 각각의 스레드 실행 => thread_main 함수 실행
for th in threads:
th.join() # 각 스레드의 종료까지 대기
print('g_count = ', g_count)
#2
:lock 함수가 임계 영역에 스레드가 들어가기 전, key를 얻어 for문을 실행#3
: 가지고 있던 key를 반환import threading
g_count = 0
def thread_main():
global g_count
lock.acquire() #2
for i in range(10000):
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) # 50개의 스레드 생성
for th in threads:
th.start() # 각각의 스레드 실행 => thread_main 함수 실행
for th in threads:
th.join() # 각 스레드의 종료까지 대기
print('g_count = ', g_count)
P(s): wait(S) {
while S <=0 // 대기
;
S--; // 다른 프로세스 접근 제한
}
V(S): signal(S) {
S++; // 다른 프로세스 접근 허용
}
P(S): wait(S) {
while S <= 0 // 바쁜 대기
;
S--; // 다른 프로세스 접근 제한
}
운영체제 기술로 보완 - 대기 큐
wait(S) {
S-> count--;
if(S->count < 0) {
add this process to S->queue;
block()
}
}
signal(S) {
S->count++;
if(S->count <= 0) {
remove a process P from S->queue;
wakeup(P)
}
}