더북(TheBook)

1.14.1 세마포어의 또 다른 용도

세마포어는 상태 값을 가지고 있으며, 그 값은 0 이상의 정수입니다. 초깃값은 앞서 설정했던 ‘최대 액세스 가능한 스레드 개수’입니다. 스레드가 세마포어에 자원 액세스를 요청하면 상태 값은 1 감소합니다. 그리고 스레드는 자원 액세스를 허가받습니다. 다른 스레드도 자원 액세스를 요청합니다. 결국 상태 값은 0이 되고 말 것입니다.

세마포어는 상태 값이 0인 상황에서는 자원 액세스를 허락하지 않기 때문에 스레드가 자원 액세스를 요청하면 그 스레드는 잠자게 됩니다. 자원 액세스를 마친 스레드는 세마포어에 ‘자원 액세스가 끝났음’을 통보합니다. 실제로 이 일은 세마포어의 상태 값을 1 증가시킵니다. 그러면 세마포어의 상태 값이 1 증가한 시점에서, 이미 어떤 스레드가 자원 액세스를 기다리고 있었다면 해당 스레드를 깨웁니다. 그리고 상태 값은 1 감소합니다.

세마포어는 이벤트와 여러모로 비슷합니다. 다만 이벤트는 상태 값이 0과 1로 제한되지만, 세마포어는 0 이상의 아무 값이나 가질 수 있다는 차이가 있습니다.

Tip

우리는 세마포어를 생성할 당시 이 상태 값의 최댓값을 지정할 수 있습니다. 이 최댓값을 1로 지정하면 세마포어는 사실상 이벤트와 동일합니다.

 

세마포어의 이러한 특성을 활용하면 우리는 재미있는 용도를 궁리해 볼 수 있습니다. 한 예를 소개합니다.

두 스레드 간에 공유되는 큐(queue)가 있다고 가정하겠습니다. 한 스레드는 큐에서 항목을 꺼내고, 큐가 비어 있으면 무언가가 들어올 때까지 잠을 잡니다. 나머지 스레드는 큐에 항목을 넣습니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.