Synchronization
Thread Synchronization
Process 내의 Thread들은 Process의 자원을 공유함
예를 들어 A Thread가 X라는 변수를 더하는 작업을 수행하고,
B라는 Thread도 X라는 변수를 더하는 작업을 수행할 때,
더한다는 작업은 하나의 Instruction으로 처리되지 않고,
X라는 변수를 불러오고, 더하고, 저장하는 일련의 작업들이 끝남으로써 완료됨
=> Programming Level에서 단일 Operation도 Instruction Level에서 여러개의 Instruction으로 나뉘어짐
그런데, A Thread가 실행되는 중 이 일련의 작업들이 끝나기 전, Time Slice 등의 이유로, 이를테면 더하고 난 뒤 저장하기 전에,
Switch가 발생하여 B Thread가 실행되게 되면, B Thread도 X를 불러오고, 더하고, 저장하는 작업을 거침
여기서 B가 불러올 때 X의 값은 A Thread에서 처리된 값이 아직 저장되지 않은 상태이기 때문에 반영되지 않은 (동기화 되지 않은) 값을 가져오게 되고, 이어서 작업을 처리한 뒤 저장하게 됨
B Thread가 작업을 다 처리한 뒤 Exit 되어 다시 A Thread가 불리면, A Thread는 바로 이어서 변수를 저장하는 작업을 수행할 것이므로, B Thread에서 저장한 X 변수 값이 그냥 덮어 씌워지는 형태가 됨
=> 이러면 결과가 예상과 다르게 됨
이러한 상황을 Race Condition 이라고 함
Race Condition
접근이 어떻게 되었는지에 따라 실행 결과가 일관성 없이 달라지는 상황,
Thread들이 공유 자원을 놓고 경쟁하는 상황을 의미
Single Core든 Multi Core든 공유하는 자원만 있다면 Race Condition 발생
Timing
Multi Threading
CPU Scheduler에 의한 예측할 수 없는 실행, 중단 타이밍
Multi Processor
각 Processor에 적재되어 있는 작업 중 누가 먼저 실행될 지
Atomic Operation
시작되면 중간에 멈추지 않고 완전히 수행되는 연산
한번에 다 실행되던가, 아니면 아예 실행이 되지 않는 Operation
Atomic Opertion에서 메모리에 접근하기는 어려움
뿐만 아니라 여러 개의 Opertion이 모두 Atomic하다는 보장이 없음
또한 Instruction Level에서의 단일 Operator도 Compiler에 의해서 Multiple Instruction으로 Compile 될 수 있음
Mutual Exclusion ( Mutex )
상호 배제
공유된 자원은 동시에 오직 한 개의 Process/Thread만 접근 가능하게 하는 것
Condition Synchronization
정의
어떤 상황을 만족할 때까지 대기하게 해서 실행 흐름을 대기 or 재개하는 방법으로 Ordering 함
Mutex를 보장하면서 순서를 보장해줌
Mutex는 실행 흐름을 보장해 주진 않음
=> 생산자 소비자 문제 참고
주의할 점
상태를 공유하는 변수가 있기 때문에, 상태 변수 전후로 Mutex가 필요함
신경 쓸 것
Condition 변수의 동기화를 위한 상태 변수의 필요 ( Condition 변수 X )
상태 변수를 위한 Mutex
상태 변수도 공유하기 때문에
반복 체킹을 위한 Loop 코드
**만약 반복 체킹을 하지 않으면,
예를 들어 소비자가 여럿이 있을 때, 한 소비자가 자원 소비를 하다가, 없어서 block되고, 생산자가 만들었지만,
이후 block됐던 소비자를 깨우지 않고, 다른 소비자를 깨우면, 다른 소비자가 만들었던 Buffer를 다 소비해 버리고, 이후 다른 사람을 깨우게 되는데,
이 때 block 됐던 소비자가 깨버리면, if문을 벗어나, 자원 섭취를 시도하게 됨
이 때 빈 버퍼에 접근해 섭취를 시도하게 되므로 에러가 남, 이러한 이유로 while문으로 반복 체킹을 해주어야 함**