
여러 주체들이 하나의 데이터에 동시에 접근하려고 할 때 Race Condition 발생 가능성
멀티프로세서에서 메모리 공유시 Race Condition문제 발생 가능성


- 본래의 의도는 ++, --가 모두 바년되어 count가 초기값이 유지되는 것이다
- 만약 Load이후 인터럽트 발생 시 인터럽트 이후의 결과는 반영되지 않고 count++만 반양
- 커널 모드의 수행이 끝나기 전에는 인터럽트를 받지 않도록 하는 (disable / enable)로 문제 해결 가능

해결법 : 커널 모드를 수행 중일 땐 CPU가 preempt되지 않도록 유지하고, 커널모드에서 유저 모드로 돌아갈 때 preempt

싱글 프로세스인 경우 인터럽트 disable / enable방법으로는 해결 가능하지만, 멀티 프로세서는 인터럽트 제어로는 해결 불가능
방법 1 : 한 번에 한 CPU만 커널에 들어갈 수 있도록 하는 방법
- 비효율적이다.
- 만약에 두 프로세서가 서로 다른 데이터에 접근하여 Race Condition 가능성이 없어도, 한 번에 한 CPU만 커널에 들어갈 수 있기 때문이다.
방법 2 : 커널 내부에 있는 공유 데이터에 접근할 때 마다 해당 데이터에 lock / unlock를 한다

Critical section : 공유 데이터를 건들이는 공간 (중요)
해당 세션은 lock을 걸고(entry section), 풀고(exit section)하는 작업이 필요.

- 상호 배제 (Mutual Exclusion)
- 동시에 들어가면 안됨
- 진행 (Progress)
- 아무도 들어가 있지 않은 상태에서, 들어가고자 하는 것이 있으면 통과 시켜줘야 한다
- 유한 대기 (Bounded Waiting)
- 대기시간은 유한해야한다

위 코드가 P0, 밑줄 친 turn={i}의 코드에서 0과 1이 바뀐 것을 P1이라고 가정
turn이라는 Synchronization variable을 두고, critical section에 들어가기전에, 이번엔 누구 차례인지 알아낸다 (한번씩 번갈아가며)
특정 프로세스가 더 들어가야하거나 상대방이 아예 안들어간다면, 즉 원하지 않는데 번갈아 들어가야한다는 단점이 존대

깃발을 두어 누가 들어가고 싶은지 보는 방법.
자신의 깃발(flag[i])을 올리고, 상대방의 깃발(flag[j])를 확인한 뒤에 critical section에 입장
동시에 들어가는 방법은 깃발을 통해 방지하지만, '진행'에 있어서 문제가 있다.
위 두가지 방법을 합친 방법이다.
모든 조건을 만족하며 해결할 수 있다.
내 깃발을 들고, 상대방 깃발이 들려있는지 && 상대방 차례면 -> 기다림!
하지만 Busy Waiting(spin lock)이라는 문제 발생 가능성 있음.
while을 빠져나갈려면 상대방이 turn을 줘야하는데, while때문에 CPU를 줄 수가 없다는 문제
소프트웨어적으로 Process Synchronization 해결
하드웨어적으로 Process Synchronization 해결


race condition 문제를 쉽게 해결 가능
상대방이 V연산을 하기 전에 자신은 P만 진행하기 때문에 busy-wait을 해야한다.
이를 해결하기 위해서 Block/Wakeup 방법을 사용하면 된다



P
S.value -> 자원이 없는 상태
자원이 생기면 block()이 생성
V
S.value() <= 0
- 누군가가 자원을 기다리고 있다는 상황


순서를 바꿔서 Deadlock 해결


Producer (생산자)
Consumer
주황색 버퍼는 생산자가 데이터를 만들어서 집어놓은 상태
아니면 이미 만들어놓은 버퍼를 소비자가 사용한 경우
공유버퍼에 대해 lock 을 걸었다가 풀어야 함
생산자 소비자 문제
- 버퍼가 bounded 생산자가 한꺼번에 도착해서 버퍼가 다 채워졌을 때, 소비자는 안 오고 생산자는 계속 버퍼를 만든다
- 사용할 수 있는 자원 부족 (소비자가 가져가야지만 버퍼를 사용 가능)
- 생산자는 빈 버퍼가 생길 때 까지 대기.
- 버퍼가 없으면 소비자가 기다려야 한다.
여러 명의 Readers, Writers 가 하나의 저장 공간(버퍼)를 공유하며 이에 접근할 때 발생
한 process 가 DB에 작성 중일 때 다른 precess가 접근하면 안된다 (동시 접근 x)
read는 동시에 여럿이 해도 된다 (read는 동시에 해도 되는데 하나 밖에 못하게 하면 비효율적)
Reader
db lock 걸기
readcount : 몇 명이 읽었는지
최초의 reader -> lock 걸어야 함
다음 reader들 -> 바로 읽는다
db lock 풀기
공유 변수 readcount를 위해 mutex에 lock을 걸 필요가 있음

생각, 배고픔 시간은 다르지만 젓가락은 하나
모두가 동시에 배고파졌을 때 -> 왼쪽 젓가락을 모두 들었을 때 발생

semaphore self[5] = 0
- 5번 철학자는 두 개의 젓가락을 잡을 수 없다.
semaphore mutex = 1
- 공유 변수에 대해 동시 접근 막기 위해
- 코딩 어려움
- 정확성 입증 어려움
- 자발적 협력 필요
- 한번의 실수가 모든 시스템에 치명적

monitor는 동시접근이 기본으로 막아져 있기 때문에 lock 필요 없음

공유자원 선언, 프로시저, 초기화 코드가 포함된 병렬식 구조 -> lock필요없음



condition variable -> empty, full
wait
자원이 없으면 프로세스가 줄을 서서 대기.
x.wait() 을 호출한 프로세스는 다른 프로세스가 x.signal() 을 호출하기 전까지 sleep
signal
모니터에 접근하고 빠져나갈 때 signal 연산을 호출해서 기다리는 프로세스가 모니터에 접근할 수 있도록 한다.
x.signal() 은 정확하게 하나의 잠이 든 프로세스를 깨운다.
잠이 든 프로세스가 없으면 아무 일도 일어나지 않는다.
