같은 계좌에서 한 명은 ATM기에서 출금하고, 다른 한 명은 어플로 출금할 때:돈을 빼고 뺀 값을 저장하는데 뺀 값을 저장하기 전에 context swtich가 일어나면 돈이 복사가 됨
Producer Consumer 구조에서 Bounded buffer Issue가 발생할 때:
버퍼에 저장하면 count++, 읽으면 count—하는데 후위연산자 자체를 어셈블리어로 보면, temp = count, temp = temp + 1, count = temp라서 그 사이에 context swtich가 일어나면 Issue 발생
결국 한 행동이 한 덩어리의 움직임이 아니라 여러 가지의 행동을 합친 행동이라서 행동하는 사이에 context swtich가 일어나 Synchronization Issue가 발생
두 개 이상의 프로세스나 쓰레드가 같은 공유 메모리를 사용할 때 발생
Race Condition
Critical Section
한 덩어리의 움직임이 아니라서 일어나는 것이기 때문에
이를 한 덩어리로 뭉치는 방법이 해결책
Mutual Exclusion (Mutex)
상호배타적! 공유 자원에 접근하는 것들은 무조건 하나여야 하는 조건
Progress
Critical Section을 실행하는 자가 아무도 없으면 기다림 없이 바로 사용
Bounded Waiting
Critical Section을 실행하기 위해 기다리는 시간이 유한적
Locks
low level단에서 접근하지 못하도록 전역변수를 통해 조건문을 다룸
Mutex lock(blocked lock)
Locks에서 조금 추가한 것
Semaphores
Lock기능을 응용해 만든 것
Monitors
자바에서 만든 것처럼 high level, 컴파일러들이 Lock Unlock을 관리
Messages
distributed systems(분산 시스템)에서 쓰므로 일반적으로는 잘 안씀
lock(), unlock(): 아무도 못 쓰게 자물쇠를 잠구고, 다 사용했으면 푼다는 뜻
spinlock: lock에서 while(l->held);
를 통해 held가 1이라면 while문 안에서 갇혀 뱅글뱅글 돈다고 해서 spinlock, unlock은 l->held = 0
으로 설정하면서 다른 프로세스가 while문을 빠져나오도록 함
하지만 held 또한 전역변수 공유자원이고 held = 1, held = 0
같은 선언문조차도 어셈블리어로 보면 여러 단계로 나뉘어져있어서 중간에 context swtich가 일어날 경우 똑같은 문제 발생
앞에서 말했지만 여러단계의 행동을 최소단위 한 덩어리로 만들면 됨
Software-only algorithms
알고리즘 1, 2, 3이라는 소프트웨어로 구현된 알고리즘을 사용하지만 high level에다가 오버헤드가 크기 때문에 잘 쓰지 않는 방식
Hardware atomic instructions
instruction을 atomic하게 한 큐에 최소단위로 처리
Test-and-set(대체로 많이씀)
RISC인데도 CISC처럼 한 덩어리의 instruction으로 설계
compare-and-swap(인텔기반에서 씀)
Test and set이랑 비슷한데 변수 한 개 더 있는 차이
Disable/re-enable interrupts
그냥 interrupt 기능을 비활성화하면 context swtich가 일어나지 않음
count가 1또는 0이어서 Binary 라고 부름
정수형이어서 여러개의 쓰레드가 동시사용가능해서 Mutex하지 않음
여러 프로세스가 서로 wait()를 하다가 꼬여서 서로를 기다리는 상황
자바에서만 쓰이는 컴파일러에서 자체적으로 lock, unlock의 기능을 제공