나무모에 미러 (일반/어두운 화면)
최근 수정 시각 : 2024-04-06 16:58:09

세마포어


파일:나무위키+유도.png  
은(는) 여기로 연결됩니다.
나폴레옹 전쟁 시기의 통신 수단 및 기술에 대한 내용은 세마포어 통신 문서
번 문단을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
참고하십시오.
1. 개요2. 왜 필요한가3. 작동 원리4. 방법
4.1. Busy Waiting4.2. 대기 큐(Blocked Queue)
5. 어원6. 관련 문서

1. 개요

세마포어(semaphore)는 에츠허르 다익스트라가 제안한 교착 상태에 대한 해법으로 두개의 atomic한 함수로 제어되는 정수 변수로 멀티프로그래밍 환경에서 공유자원에 대한 접근 제어를 하는 방식으로 1개의 공유되는 자원에 제한된 개수의 프로세스, 또는 스레드만 접근할 수 있도록 한다. 세마포어의 카운트는 1 이상이며 카운트를 조절하여 진입 가능한 프로세스/스레드 수를 조절할 수 있다. 세마포어 카운트가 항상 1인 것은 아니다.

다만, 해당 방법은 모든 교착 상태에 대한 해답을 제시해 줄 수 없으나 교착 상태 해법에 대한 고전적인 해법으로 아직도 대다수의 운영체제 과목 및 시스템 프로그래밍 과목에서 언급되는 개념이다. 이 방법으로 해결되는 대표적인 문제가 식사하는 철학자 문제다.

2. 왜 필요한가

예를 들어, 아래의 변수가 있다고 하자.

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가 시작되도록 다시 시작하게 하면 해결된다.

3. 작동 원리

세마포어의 작동 원리는 상호 배제 알고리즘(Mutual Exclusion)에 기반한다. 세마포어는 원자적으로 제어되는 정수 변수로, 일반적으로 세마포어의 값이 0이면 자원에 접근할 수 없도록 블럭을 하고 0보다 크면 접근함과 동시에 세마포어의 값을 1 감소시킨다. 반대로 종료하고 나갈 때에는 세마포어의 값을 1 증가시켜 다른 프로세스가 접근할 수 있도록 한다. 여기서 접근되는 자원은 임계 구역으로 이 설정에 따라서 프로그램의 퍼포먼스가 극단적으로 하락할 수 있어 사용에 세심한 주의가 필요하다.[1]

4. 방법

4.1. Busy Waiting

최초에 제시된 방안으로 바쁜 대기를 하게 된다. 바쁜대기란 아무것도 하지 않는 빈 반복문을 계속 돌다가 임계 구역에 진입할 수 있을 때 진입하는 방식으로, 빈 반복문을 반복하기 때문에 계속적으로 컨텍스트 교환이 발생하며 이로 인하여 처리 효율이 떨어지는 단점이 있다. 또한, 어떠한 프로세스가 먼저 임계 구역에 진입을 할 수 있을지에 대한 처리를 할 수 없다는 단점 또한 존재한다.

4.2. 대기 큐(Blocked Queue)

세마포어의 값이 0(nonpositive)이면 이후에 진입하는 프로세스 A는 스스로를 대기 상태로 만들고(blocked) 해당 프로세스의 제어 블록(PCB)를 대기 큐에 삽입한다. 이후 다른 프로세스 B가 종료되어 세마포어의 값이 양수가 되면 해당 프로세스 B는 대기 큐의 A를 제거하고 A를 준비 상태(ready)로 변경한 뒤 준비 큐로 옮긴다.

5. 어원

깃발이란 뜻이며, 근대부터는 철도 용어로 쓰였다.

여러 대의 기차가 하나의 철로를 공용하여 쓸 때, 오직 하나만 지나갈 수 있도록 하기 위해 양쪽 끝 선에 깃발 표시를 하여 사고가 안나게 하였던 장치이다.

프로그래밍에서도 원리를 동일하게 적용하여, 여러개의 스레드/프로세스기차가 하나의 공유 자원/루틴철로으로 접근할 때, 스레드 세이프를 유지한다.

6. 관련 문서


[1] 디자인 패턴의 싱글톤 패턴을 생각해보면 이해가 용이하다. 여러개의 스레드가 1개의 싱글톤 패턴으로 만들어진 오브젝트를 이용하려 할 때가 제어를 하는것이 바로 세마포어가 하는것과 동일한 역할이다.