[목차] == 설명 == 세마포어(semaphore)는 [[에츠허르 다익스트라]]가 제안한 교착 상태에 대한 해법으로 두개의 atomic한 함수로 제어되는 정수 변수로 멀티프로그래밍 환경에서 공유자원에 대한 접근 제어를 하는 방식으로 1개의 공유되는 자원에 제한된 개수의 프로세스, 또는 스레드만 접근할 수 있도록 한다. 세마포어의 카운트는 1 이상이며 카운트를 조절하여 진입 가능한 프로세스/스레드 수를 조절할 수 있다. 세마포어 카운트가 항상 1인 것은 아니다. 다만, 해당 방법은 모든 교착 상태에 대한 해답을 제시해 줄 수 없으나 교착 상태 해법에 대한 고전적인 해법으로 아직도 대다수의 [[운영체제]] 과목 및 시스템 프로그래밍 과목에서 언급되는 개념이다. 이 방법으로 해결되는 대표적인 문제가 [[식사하는 철학자 문제]]다. == 왜 필요한가 == 예를 들어, 아래의 변수가 있다고 하자. int a = 0; 이러한 상황에 해당 값은 전역 변수로 설정되어있고, 이 프로그램은 여러 개의 스레드가 a의 값을 증가시키는 프로그램이라고 할 때 이러한 증상이 발생한다. Process A → fetch a(0) Process B → fetch a(0) Process A → increase a(1) Process A → Store a back(1) Process B → increase a(1) Process B → Store a back(1) 여기서, 외부에서 보게 되면 변수 a에 대해서 1씩 증가하는 과정이 2번 일어났다. 그러므로 B 프로세스가 종료되었을 때는 a는 2가 되어야 하나 여기서는 1이 되어버렸다. 즉, A가 결과를 주기 전에 B가 수행되면서 엉뚱한 값을 시작값으로 가져와서 결과가 잘못 나와 버렸다. 이를 방지하기 위해서 세마포어를 이용하여 a 변수에 Process A가 접근 하고 있을 때 Process B를 정지시키고 Process A가 종료 되었을 때 B가 시작되도록 다시 시작하게 하면 해결된다. == 작동 원리 == 세마포어의 작동 원리는 상호 배제 알고리즘([[뮤텍스|Mutual Exclusion]])에 기반한다. 세마포어는 원자적으로 제어되는 정수 변수로, 일반적으로 세마포어의 값이 0이면 자원에 접근할 수 없도록 블럭을 하고 0보다 크면 접근함과 동시에 세마포어의 값을 1 감소시킨다. 반대로 종료하고 나갈 때에는 세마포어의 값을 1 증가시켜 다른 프로세스가 접근할 수 있도록 한다. 여기서 접근되는 자원은 [[뮤텍스#s-2.1|임계 구역]]으로 이 설정에 따라서 프로그램의 퍼포먼스가 극단적으로 하락할 수 있어 사용에 세심한 주의가 필요하다.[* 디자인 패턴의 싱글톤 패턴을 생각해보면 이해가 용이하다. 여러개의 스레드가 1개의 싱글톤 패턴으로 만들어진 오브젝트를 이용하려 할 때가 제어를 하는것이 바로 세마포어가 하는것과 동일한 역할이다.] == 방법 == === Busy Waiting === 최초에 제시된 방안으로 바쁜 대기를 하게 된다. 바쁜대기란 아무것도 하지 않는 빈 반복문을 계속 돌다가 [[뮤텍스#s-2.1|임계 구역]]에 진입할 수 있을 때 진입하는 방식으로, 빈 반복문을 반복하기 때문에 계속적으로 컨텍스트 교환이 발생하며 이로 인하여 처리 효율이 떨어지는 단점이 있다. 또한, 어떠한 프로세스가 먼저 임계 구역에 진입을 할 수 있을지에 대한 처리를 할 수 없다는 단점 또한 존재한다. == 어원 == 깃발이란 뜻이며, 근대부터는 [[철도]] 용어로 쓰였다. 여러 대의 기차가 하나의 철로를 공용하여 쓸 때, 오직 하나만 지나갈 수 있도록 하기 위해 양쪽 끝 선에 깃발 표시를 하여 사고가 안나게 하였던 장치이다. 프로그래밍에서도 원리를 동일하게 적용하여, 여러개의 스레드/프로세스^^기차^^가 하나의 공유 자원/루틴^^철로^^으로 접근할 때, 스레드 세이프를 유지한다. == 관련 문서 == * [[뮤텍스]](mutex) [[분류:컴퓨터 공학]][[분류:운영 체제]]