세마포어
는 여러 프로세스들의 공유 자원에 대한 접근 제어와 동기화를 지원하기 위한 정수로 선언된 동기화 도구이다.스핀락(spin lock)
처럼 busy waiting으로 구현되지 않는다.세마포어(S
)는 wait
과 signal
이라는 atomic한 두 개의 연산을 갖는다.
[세마포어의 Wait 연산]
Function wait(S) is if S > 0 then /* 프로세스를 block 시키지 않는다 */ S = S - 1; return; else /* 프로세스를 block 시킨다. */ sleep; end end
- 세마포어(S)가 0보다 크면, 할당할 수 있는 공유 자원이 있다는 뜻이므로 세마포어 값을 1 감소시킨다.
- 세마포어(S)가 0이면, 할당할 수 있는 공유 자원이 없다는 뜻이므로 프로세스가 sleep 상태가 된다.
[세마포어의 Signal 연산]
Function Signal(S) is if there a process sleeping on S then select a process to wake up; wake up the selected process; return; else S = S + 1; return; end end
- sleep 상태의 프로세스가 존재하지 않는다면, 공유 자원을 할당받기 위해 대기하고 있는 프로세스가 없다는 뜻이므로 세마포어 값을 1 증가시킨다.
- sleep 상태의 프로세스가 존재하면, 세마포어 값을 증가시키는 것 대신에 sleep 상태인 프로세스를 깨우고 그 프로세스에게 자원을 할당한다.
Binary Semaphore
Counting Semaphore
busy waiting
대신 프로세스는 sleep 상태에 들어간다. 임계 구역에서 동작을 끝낸 프로세스가 signal
연산을 통해 세마포어 값을 증가시키면 커널은 sleep 상태에 있는 프로세스를 ready queue
로 이동시키고, 프로세스는 임계 구역 안으로 진입할 수 있다.wait(x)
연산 없이 S1 영역에 진입한 뒤, signal(x)
연산을 통해 x 값을 증가시킨다.wait(x)
연산을 수행하기 때문에 Process 0이 signal(x)
연산을 수행할 때 까지 sleep 상태에 놓이게 된다.wait(empty)
연산을 통해 버퍼에 빈 공간이 있는지 확인한다. 빈 공간이 있다면 버퍼에 데이터를 저장하고 (버퍼 또한 임계 구역이므로 wait(S) 연산을 통해 진입한다.) signal(full)
연산을 수행하여 Consumer가 버퍼에 접근할 수 있도록 한다.wait(full)
연산을 통해 버퍼에 데이터가 저장되어 있는지 확인한다. 버퍼에 데이터가 저장되어 있다면 데이터를 읽고 signal(empty)
연산을 수행하여 Producer가 버퍼에 데이터를 저장할 수 있도록 한다.wait()
과 signal()
메소드를 사용해서 공유 자원에 대한 사용 여부(?)를 나타낸다.