{{위키데이터 속성 추적}}
{{다른 뜻}}
'''세마포어'''(Semaphore)는 [[에츠허르 데이크스트라]]가 고안한, 두 개의 원자적 함수로 조작되는 정수 변수로서, [[멀티프로그래밍]] 환경에서 공유 자원에 대한 접근을 제한하는 방법으로 사용된다. 이는 [[철학자들의 만찬 문제]]의 고전적인 해법이지만 모든 [[교착 상태]]를 해결하지는 못한다.

실제 시스템에서 사용되는 세마포어를 생각하는 유용한 방법은 특정 리소스의 몇 단위를 사용할 수 있는지에 대한 기록과 해당 레코드를 안전하게 조정하는 작업(즉, 경쟁 조건을 피하기 위해)을 결합하는 것이다. 획득하거나 무료가 되며, 필요한 경우 리소스 단위를 사용할 수 있을 때까지 기다린다.

세마포어는 경쟁 조건을 방지하는 데 유용하지만, 경쟁 조건이 없다고 보장하지는 않는다. 임의의 자원 수를 허용하는 세마포어를 카운팅 세마포라고 하며, 값 0과 1(또는 잠김/잠금 해제, 사용 불가능/사용 가능)로 제한되는 세마포를 이진 세마포라고 하며 잠금을 구현하는 데 사용된다.

세마포어 개념은 데이크스트라와 그의 팀이 일렉트롤로지카(Electrologica) X8용 [[운영체제]]를 개발하던 1962년 또는 1963년에 네덜란드 컴퓨터 과학자 [[에츠허르 데이크스트라]]에 의해 발명되었다. 이 시스템은 결국 다중 프로그래밍 시스템으로 알려지게 되었다.

== 구성 ==
세마포어 S는 정수값을 가지는 변수이며, 다음과 같이 P와 V라는 명령에 의해서만 접근할 수 있다. (P와 V는 각각 try와 increment를 뜻하는 [[네덜란드어]] {{lang|nl|Proberen}}과 {{lang|nl|Verhogen}}의 머릿글자를 딴 것이다.)

P는 [[임계 구역]]에 들어가기 전에 수행되고, V는 [[임계 구역]]에서 나올 때 수행된다. 이때 변수 값을 수정하는 연산은 모두 [[원자성]]을 만족해야 한다. 다시 말해, 한 프로세스(또는 스레드)에서 세마포어 값을 변경하는 동안 다른 프로세스가 동시에 이 값을 변경해서는 안 된다.

== 적용 ==
=== 방법 1 ===
최초 제시된 방법은 [[바쁜 대기]](busy waiting)을 이용한 방법이다.
<syntaxhighlight lang="text">
 P(S) {
     while S <=0; // 아무것도 하지 않음 (반복문)
     S--;
 }

 V(S) {
     S++;
 }
</syntaxhighlight>
이 방법은 임계 구역에 들어갈 수 있을 때까지 빈 반복문을 수행하기 때문에, [[단일처리기]] [[다중프로세스]] 환경에서 처리기 효율이 떨어진다. 또한 대기 중인 프로세스들 중 어느 것을 먼저 임계 구역에 진입시킬지를 결정할 수 없다.

=== 방법 2 ===
최초 방법의 단점을 보완한 방법으로서 재움 큐를 활용하여 프로세스를 재우는 방식이다.
<syntaxhighlight lang="text">
 P(S) {
     S--;
     if S < 0
         // 이 프로세스를 재움 큐에 추가 (잠 듦)
 }

 V(S) {
     S++;
     if S <= 0
         // 재움 큐로부터 프로세스를 제거 (깨어남)
 }
</syntaxhighlight>

== 종류 ==
=== 계수 세마포어 ===
계수 세마포어(counting semaphore)에서는 초기값은 가능한 자원의 수로 정해지며, 세마포어 값의 범위는 정해져 있지 않다.
=== 이진 세마포어 ===
이진 세마포어(binary semaphore)에서는 세마포어 값으로 0 또는 1을 가진다. 계수 세마포어보다 간단히 구현할 수 있으며, [[Test and Set]] 등 하드웨어가 지원하는 기능을 이용하여 구현하기도 한다. 또한, 이진 세마포어를 이용하여 계수 세마포어를 구현할 수도 있다.

== 약점 ==
* P함수와 V함수의 동작은 독립적이기 때문에 잘못 사용하는 경우 문제가 발생한다.
** P - 임계 구역 - P : 현재 프로세스가 임계 구역에서 빠져나갈 수 없게 된다. 또한 다른 프로세스들은 임계 구역에 들어갈 수 없으므로 [[교착 상태]](Deadlock)가 발생한다.
** V - 임계 구역 - P : 2개 이상의 프로세스가 동시에 임계구역에 들어갈 수 있으므로 [[상호 배제]](Mutual Exclusion)를 보장할 수 없게 된다.
* 고급 언어에서 동기화를 제공해야 한다.

== 참고 ==
세마포어(semaphore)의 원래 뜻은 기차 등에서 사용하는 '까치발 신호기'이다.

== 같이 보기 ==
* [[생산자-소비자 문제]]
* [[독자-저자 문제]]
* [[철학자들의 만찬 문제]]

== 출처 ==
*{{Cite EWD|123|Cooperating sequential processes}} (September 1965)
*{{인용|mode=cs1 |url=http://www.opengroup.org/onlinepubs/009695399/basedefs/semaphore.h.html |section=semaphore.h - semaphores (REALTIME) |title=The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition |publisher=Open Group |date=2004}}
*{{웹 인용|url= http://greenteapress.com/semaphores/ |title= The Little Book of Semaphores |first= Allen B. |last= Downey |publisher= Green Tea Press |issue= 2.2.1 |edition= 2nd |date= 2016 |orig-year= 2005 }}
*{{웹 인용 |url= http://www.enseignement.polytechnique.fr/informatique/INF431/X09-2010-2011/AmphiTHC/SynchronizationPrimitives.pdf |title= A pragmatic, historically oriented survey on the universality of synchronization primitives |first= Jouni |last= Leppäjärvi |date= May 11, 2008 |location= University of Oulu, Finland |확인날짜= 2024-06-07 |archive-date= 2017-08-30 |archive-url= https://web.archive.org/web/20170830062719/http://www.enseignement.polytechnique.fr/informatique/INF431/X09-2010-2011/AmphiTHC/SynchronizationPrimitives.pdf |url-status=  }}

== 외부 링크 ==
* [https://www.joinc.co.kr/w/Site/system_programing/IPC/semaphores 세마포어의 사용]

{{자료형}}
{{병렬 컴퓨팅}}

[[분류:동기화]]
[[분류:동시성 제어]]
[[분류:병행성]]
[[분류:병렬 컴퓨팅]]
[[분류:컴퓨터 매개 통신]]
[[분류:에츠허르 데이크스트라]]
[[분류:네덜란드의 발명품]]