멀티스레드 프로그램에서는 여러 thread가 동시에 실행된다.
이때 global variable, heap object, kernel data structure와 같은
shared resource에 동시에 접근하면 문제가 발생할 수 있다.
이러한 문제를 방지하기 위한 메커니즘이 바로 Synchronization이다.
핵심 목적:
한 시점에 오직 하나의 execution context만
critical code를 실행하도록 보장하는 것
Critical Section이란 여러 thread 또는 execution context가
공유 자원에 접근하는 코드 영역을 의미한다.

이 영역은 반드시 atomic하게 실행되어야 한다.
do {
entry section // lock 획득
critical section // shared resource 접근
exit section // lock 해제
remainder section // 나머지 코드
} while (true);
void foo() {
int a = 0;
a++;
}
👉 Synchronization 불필요
int i; // global variable
👉 Critical Section 필요
👉 Critical Section 필요
i++는 atomic하지 않은가?int i;
void foo() {
i++;
}
i++는 한 줄 코드지만 실제로는 다음 단계로 실행된다.
i 값을 register로 load👉 여러 instruction으로 구성
👉 atomic operation 아님

i = 7결과: i = 9

i = 7을 read결과: i = 8 (incorrect)
Linux kernel에서는 단순히 thread만 고려하면 안 된다.

👉 kernel에서는 훨씬 더 많은 race scenario가 존재
queue_t *shared_q;
my_irq_handler() {
tmp = io(...);
push(shared_q, tmp);
}
my_read() {
n = length(shared_q);
if (n > 0) {
buf = kmalloc(1024);
pop(shared_q, buf);
}
}
shared_q는 shared resource👉 push, pop, length 모두 critical section



buf = kmalloc(1024); // sleep 가능
👉 상태 불일치 위험