본문 바로가기
CS study/Operating System

8. 운영체제 Condition Variables

by 규나 2021. 9. 22.
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

  1. 위 예제에서 done 변수가 없으면 deadlock이 발생해서 부모 쓰레드는 영원히 잠들게 될 것
  2. 위 예제에서 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

댓글