운영체제를 공부하기 위해 운영체제 아주 쉬운 세 가지 이야기 라는 책을 읽고 공부한 내용을 정리합니다.
잘못되거나 부족한 부분이 있으면 언제든 댓글로 가르침 부탁드립니다.
쓰레드가 계속 진행되기 위해서는 특정 조건이 만족하는지 검사해야 하는 경우가 발생한다. 이떄 컨디션 변수 를 활용할 수 있다. 컨디션 변수는 어떤 실행의 상태가 원하는 것과 다를 때 조건이 참이 되기를 기다리며 스레드가 대기할 수 있는 큐이다. 또한 컨디션 변수에는 2개의 연산이 있다.
wait()
: 조건이 만족하지 않아 스레드를 재운다.(큐에 넣는다.)
signal()
: 조건이 만족해서 다른 스레드를 깨운다.
wait은 락을 갖고 있다고 가정하고 작동되기 때문에, 호출자를 잠들게 할 떄 락을 해제하고 리턴하기 직전에 락을 다시 획득해야 한다.
세마포어를 ‘공유 자원에 접근할 수 있는 권한의 개수이자, 음수일 때는 대기중인 스레드의 개수’ 정도로 이해하면 조금 더 쉽게 이해할 수 있다. 세마포어는 정수 값을 갖는 객체로서, 락과 컨디션 변수 모두로 사용할 수 있다. POSIX 표준에 따라, sem_wait()
과 sem_post()
2개의 루틴을 통해 세마포어를 조작한다.
sem_wait()
int sem_wait() {
// semaphore 값 1 감소
// semaphore < 0 이면 wait (spin 혹은 sleep)
}
sem_post()
int sem_post() {
// semaphore 값 1 증가
// 대기하고 있는 스레드가 1개 이상 있다면, 하나를 깨운다.
}
세마포어를 통해 락을 구현하는 것을 이진 세마포어라고 한다. 처음 세마포어의 값은 1이다. 즉, 공유 자원 접근 권한이 1개 있다는 뜻이다. 이때 스레드가 sem_wait()
을 실행하면 세마포어를 1 감소시켜 0으로 만들고, 음수가 아니므로 대기없이 바로 sem_wait()
에서 빠져나와 임계영역에 진입할 수 있다. 그리고 그 사이 다른 스레드의 접근이 없다면 임계영역 작업을 마치고 sem_post()
를 통해 다시 세마포어 값을 1로 원상복귀 시킨다. 만약 세마포어가 0 일때 다른 스레드가 sem_wait()
을 실행한다면 세마포어값은 음수가 되고 스레드는 대기 상태가 된다.
이진 세마포어와 거의 똑같다. 다만 세마포어를 초기화 시킬 때, 공유 가능한 자원의 개수만큼 세마포어의 값을 초기화시켜주면 된다.
교착상태란 서로가 상대방의 자원이 내놓아지기만을 무한정 기다리는 상황을 의미한다. 교착 상태가 발생하기 위해서는 아래 4가지 조건이 모두 충족되어야 한다.