문제의 복잡성이 발생하는 근본 원인은, 2.2절에서 설명된 것처럼 복잡한 해결책으로 이어지는 이유는 공유 변수에 대한 접근이 항상 "단방향 정보 흐름"이라는 사실 때문입니다. 즉, 개별 프로세스는 새로운 값을 할당하거나 현재 값을 검사할 수는 있지만, 이러한 검사는 다른 프로세스에 대해 아무런 흔적을 남기지 않습니다. 그 결과, 한 프로세스가 공유 변수의 현재 값에 반응하려 할 때, 해당 값은 검사와 그에 따른 반응 실행 사이에 다른 프로세스에 의해 변경될 수 있습니다. 다시 말해, 기존의 통신 방식은 해당 문제를 해결하기에 부적합하며, 더 적합한 대안을 찾아야 합니다.
그러한 대안은 다음과 같이 도입함으로써 제공됩니다: a) 공유 변수 중 특수 목적의 정수를 도입하는데, 이를 우리는 "세마포어(semaphores)"라고 부릅니다. b) 각 프로세스가 구성되는 동작들의 집합에 두 가지 새로운 기본 연산을 추가하며, 이를 우리는 각각 "P-연산"과 "V-연산"이라고 부릅니다. 이러한 연산들은 항상 세마포를 대상으로 작동하며, 동시 실행되는 프로세스들이 세마포어에 접근할 수 있는 유일한 방법을 나타냅니다.
세마포어는 본질적으로 음수가 아닌 정수입니다. 상호 배제(Mutual Exclusion) 문제를 해결하는 데만 사용될 경우, 그 값의 범위는 "0"과 "1"로 제한될 수도 있습니다. 더 큰 값도 가질 수 있는 세마포의 광범위한 적용 가능성을 입증한 것은 네덜란드의 물리학자이자 컴퓨터 설계자인 C.S. Scholten 박사의 공로입니다. 필요에 따라 구분할 때, 우리는 이를 각각 "이진 세마포어(binary semaphores)"와 "일반 세마포어(general semaphores)"라고 부를 것입니다. 이제부터 제가 제시할 P-연산과 V-연산의 정의는 이러한 구분에 영향을 받지 않습니다.
-다익스트라의 노트 EWD123
among the repertoire of actions, from which the individual processes have to be constructed, two new primitives, which we call the "P-operation" and the "V-operation" respectively. The latter operations always operate upon a semaphore and represent the only way in which the concurrent processes may access the semaphores.
-Dijkstra, EWD 123
이 특별한 정수는 오직 두 개의 연산만으로 조작할 수 있다:
- P 연산 (Proberen, "시험하다")
- V 연산 (Verhogen, "증가시키다")
이 두 연산은 다음과 같은 규칙을 갖는다:
| 연산 | 의미 | 효과 |
| P(s) | wait / acquire | 세마포어 값이 양수면 1 감소하고 통과, 0이면 대기 |
| V(s) | signal / release | 세마포어 값을 1 증가시킴 |
이 연산들은 항상 원자적으로 수행된다. 즉, 어떠한 중단이나 끼어듦 없이 한 번에 수행된다는 뜻
이것이 바로 우리가 찾던 “중간 개입을 차단하는 메커니즘”
그것이 세마포어이다.
현대 OS에서는 이 과정을 futex, spinlock, sleep queue 등으로 구현하는데
주의할 점은
P, V 연산 의사코드에서 `s = s - 1` 이나 `s = s + 1` 그리고 `while (s <= 0) wait;` 조건 검사 부분은 하나의 분리될 수 없는 원자적 단위로 실행되어야 한다.
여기서 `P(s)`의 `while (s <= 0) wait;` 부분이
만약 CPU를 계속 사용하면서 조건이 만족될 때까지 반복 확인하는 바쁜 대기(busy-waiting 또는 spin-waiting)라면, CPU 자원을 매우 비효율적으로 사용하게 된다. 다른 유용한 작업을 할 수 있는 CPU 시간을 낭비하는 것이다.
따라서 현대 운영체제는 이 "wait" 과정을 훨씬 효율적으로 처리하기 위해 다음과 같은 메커니즘들을 사용하는데, 이것이 현대 비동기 처리방법이라고 봐도 무방하다.
슬립 큐 (Sleep Queue / Wait Queue) 와 컨텍스트 스위칭 (Context Switching),스핀락(Spinlock),퓨텍스(Futex)
이 방식들 전반의 이론적 원점은 저 간단한 연산이다.
요약해서 현대의 OS에서 세마포어 연산을 이야기하면 다음과 같다.
- 1.기본적인 대기/깨움:슬립 큐를 사용하여 프로세스를 효율적으로 재우고 깨움 (바쁜 대기 방지).
- 2. 내부 원자성 확보: P, V 연산 자체의 아주 짧은 코드 실행 동안 세마포어 변수(`s`)나 슬립 큐를 안전하게 수정하기 위해 (커널 내부에서) 스핀락 등이 사용될 수 있음.
- 3.성능 최적화 (특히 Linux):퓨텍스를 활용하여, 경합이 없을 때는 사용자 공간에서 빠르게 처리하고, 경합이 발생할 때만 커널의 슬립 큐 기능을 사용하여 시스템 콜 오버헤드를 줄인다.
| 구분 | 의미 | 사용처 |
| Binary Semaphore | 값: 0 또는 1 | 뮤텍스(Mutex)와 동일 |
| General Semaphore | 값: 0 이상 | 제한된 자원 (예: DB 커넥션 풀)ㅇㅇ |
좋은 글인데 빡대갈인 나항테는 노무 어렵다 이기
개추좀요 감사감사
막코더 게이 세마포어를 모른다니 말도 안된다 이기
@ㅆㅇㅆ(124.216) 개추는 눌러도 추천할수 없습니다 라고 나온다 이기 대신 실베추 누름
@류도그담당(114.202) 나 개빡대갈이다 이기야
@슈퍼막코더(116.65) 행님 일본취직자이신데 백수들보다야
busy wating 돌다가 너무 길어지면 대기 상태로 만들어버린다는 말도 있던데 ㅇㅅㅇ
그렇게 구현했다는 애들도 있더라. 개추좀
2추 나다 이기야
루,리`웹 간단한 글 작성이 가능 하신분 연락주세요 (건 바이 건/사례 有) 텔 @ Âďzč5
개추 ㅇㅅㅇ
고맙다
멋지당~ 이런 글 블로그에 쓰는거 어떰?
난 이렇게 정리했었는데 https://until.blog/@cs/semaphore
나 csdn 블로그 있어
우연히 갤 들어왔는데 양질의 글 감사합니다.
예시를 보다보니까 커넥션 풀이 생각나네 - dc App
운영체제 공부하다가 세마포어 보고 좆같았는데 무슨 잠금 장치 비유니 P 니 V니 wait니 signal이니 mutex니 하는것들인데 글 정리 잘해줬다
np라는거네