SMALL
Conditional Execution
- multi-thread 프로그램에서 쓰레드 실행 순서를 컨트롤하여 특정 조건에서 작동하도록 하고 싶은 경우가 있을 수 있다.
- shared variable(공유변수)을 사용해서 conditional execution을 강제할 수 있지만, 부모 쓰레드의 spin wait으로 인해 CPU낭비가 발생함

Condition Variable
- wait : 현재 state가 조건과 맞지 않으면 쓰레드가 자기 자신을 queue에 삽입
- signal : 만약 다른 쓰레드가 state를 변경하면 대기중인 쓰레드 하나를 깨움
Condition Variable Functions

- pthread_cond_wait()
- 락을 해제하고 sleep 상태로 들어감
- 다시 일어날 때에는 가장 먼저 락을 획득해야함
- pthread_cond_signal()
- 쓰레드가 state를 변경하고 나서 그 state를 기다리던 쓰레드를 깨움

예제 revisit
- 위 예제에서 done 변수가 없으면 deadlock이 발생해서 부모 쓰레드는 영원히 잠들게 될 것

- 위 예제에서 mutex lock은 변수 done을 보호하기 위해 사용됨. mutex lock이 없으면 아래 그림에서 wait() 호출 직전에 인터럽트가 발생해서 자식 쓰레드가 실행되면 부모 쓰레드는 영원히 잠들게 될 것

Producer-Consumer Problem
- Producer는 data를 생성하고 공유 버퍼에 삽입
- Consumer는 공유 버퍼에서 data를 꺼내서 소비
Producer-Consumer Problem 코드 구현
- 공유 버퍼인 queue는 공유되므로, mutex lock으로 보호되어야 함

- 버퍼는 circular queue처럼 동작하고 put()과 get()함수는 enqueue와 dequeue로 동작함

Race Condition in Producer-Consumer Problem
아래 그림의 시나리오처럼 race condition이 발생할 수 있다.

- 해결책은 wait() 함수를 호출할 때 if문이 아니라 while문을 쓰면 된다. while문을 쓰면 consumer가 sleep 상태에서 깨어날 때 상태를 재확인하여 문제를 예방한다.

Signaling Semantics
Spurious wakeups(거짓으로 깨우는 것) : 어떤 시스템들은 signaling을 할 때 여러개의 쓰레드를 깨운다. 이러한 경우 if문이 아닌 while문으로 상태를 재확인하면 race condition을 피할 수 있다.
- Mesa Semantics
- 쓰레드를 깨우기 위해 signaling을 할 때 그것은 단지 상태가 변화되었다는 의미일 뿐 원하는 상태가 되었음을 알리는 것이 아니다.
- Hoare Semantics
- mesa semantic과 반대로 원하는 상태가 만족되었을 때 쓰레드를 깨운다. 근데 구현하기 힘들어서 대부분 시스템에서 사용하지 않는다.
Deadlock in Producer Consumer Problem
아래 그림의 시나리오처럼 deadlock이 발생할 수 있다.

- 해결책은 Producer와 Consumer에 서로 다른 condition variable을 두는 것
- Producer는 Consumer를 깨우고, Consumer는 Producer를 깨운다.

'CS study > Operating System' 카테고리의 다른 글
| 9. 운영체제 Semaphore (0) | 2021.09.23 |
|---|---|
| 7. 운영체제 Lock (0) | 2021.09.20 |
| 6. 운영체제 Threads (0) | 2021.09.18 |
| 5. 운영체제 paging (0) | 2021.09.17 |
| 4. 운영체제 Virtual Memory (0) | 2021.09.15 |
댓글