Foundry
운영체제
중급
핵심

뮤텍스 vs 세마포어

상호 배제와 동기화 메커니즘 비교

뮤텍스 vs 세마포어

여러 스레드/프로세스가 공유 자원에 동시 접근하는 것을 제어하는 동기화 도구

뮤텍스 (Mutex)

[화장실 열쇠 1개]

Thread A: 열쇠 획득 (lock) 🔑
         → 화장실 사용 중 🚽
Thread B: 대기... ⏳
Thread A: 열쇠 반납 (unlock)
Thread B: 열쇠 획득 → 사용
  • 상호 배제 (Mutual Exclusion)
  • 열쇠 1개 = 한 번에 1개만 접근
  • 소유권 있음 (잠근 스레드만 풀 수 있음)

세마포어 (Semaphore)

[주차장 빈 자리 3개]

count = 3
Car A 입장: count = 2 (P 연산)
Car B 입장: count = 1
Car C 입장: count = 0
Car D: 대기... (count = 0)
Car A 출차: count = 1 (V 연산)
Car D 입장: count = 0
  • 카운팅 방식 (동시 N개 허용)
  • 소유권 없음 (다른 스레드가 signal 가능)

핵심 차이

구분뮤텍스세마포어
동시 접근1개만N개까지
소유권있음없음
용도상호 배제리소스 카운팅
비유열쇠 1개주차장 카운터
0 또는 10 ~ N

이진 세마포어 vs 뮤텍스

이진 세마포어: count = 0 또는 1
뮤텍스: lock/unlock

비슷해 보이지만 다름!
- 뮤텍스: 소유권 (A가 잠그면 A만 풀 수 있음)
- 이진 세마포어: 소유권 없음
- 뮤텍스: 우선순위 역전 방지 가능

동기화 문제들

문제설명해결
경쟁 조건동시 접근으로 결과 불일치뮤텍스/세마포어
데드락서로 잠금 대기순서 통일, 타임아웃
기아특정 스레드 영원히 대기공정 스케줄링
우선순위 역전낮은 우선순위가 잠금 보유우선순위 상속

실무 활용

상황도구
DB 커넥션 풀 (max 10)세마포어(10)
파일 쓰기뮤텍스
Rate Limiting세마포어
싱글톤 초기화뮤텍스
면접에서 이렇게 나옵니다

Q.뮤텍스와 세마포어의 차이를 설명해주세요.

소유권이 있는지가 핵심입니다.

항목뮤텍스세마포어
목적상호 배제자원 개수 관리와 신호 전달
잠김과 풀림0 이상의 정수
소유권있다. 잠근 스레드만 푼다없다. 누구나 올릴 수 있다
동시 통과하나초기값만큼

소유권이 실무에서 중요한 이유는 실수를 잡아주기 때문입니다. 다른 스레드가 남의 잠금을 푸는 코드는 뮤텍스에서 오류로 드러나지만 세마포어에서는 조용히 통과해 두 스레드가 동시에 임계 구역에 들어갑니다.

세마포어는 상호 배제 말고도 쓸 수 있습니다. 한쪽이 신호를 올리고 다른 쪽이 기다리는 생산자 소비자 구조가 그것입니다. 뮤텍스로는 그 표현이 안 됩니다.

흔한 실수: 세마포어를 "여러 개 통과시키는 뮤텍스"로만 답하는 것. 소유권 유무와 신호 전달 용도가 더 본질적인 차이입니다.

Q.이진 세마포어와 뮤텍스의 차이는?

값의 범위는 같지만 소유권과 용도가 다릅니다.

항목이진 세마포어뮤텍스
0 또는 1잠김과 풀림
잠근 주체만 해제아니다그렇다
초기값0 으로 시작할 수 있다항상 풀린 상태로 시작
재진입없다구현에 따라 지원한다
우선순위 역전 대응없다상속 기법을 지원하는 구현이 있다

초기값 0 이 가능하다는 점이 용도 차이를 만듭니다. 세마포어는 아직 아무도 안 가진 상태로 시작해, A 가 신호를 올릴 때까지 B 가 기다리는 순서 제어에 쓸 수 있습니다. 뮤텍스는 이 표현이 안 됩니다.

흔한 실수: 둘이 사실상 같다고 답하는 것. 상호 배제에는 뮤텍스를 쓰는 것이 원칙이고, 이유는 남이 푸는 실수를 막고 우선순위 역전 대응이 가능하기 때문입니다.

Q.경쟁 조건(Race Condition)이란 무엇인가요?

여러 실행 흐름이 공유 자원에 동시에 접근할 때, 실행 순서에 따라 결과가 달라지는 상태입니다.

스레드 A 는 잔액에 100을 더하고, B 는 50을 뺀다
순서동작잔액
1A 가 읽는다1000
2B 가 읽는다1000. 아직 A 가 쓰지 않았다
3A 가 쓴다1100
4B 가 쓴다950. A 의 변경이 사라졌다

원인은 읽고 계산해서 쓰는 것이 원자적이지 않기 때문입니다. 중간에 끼어들 틈이 있습니다.

해결방법
잠금임계 구역을 뮤텍스로 감싼다
원자적 연산하드웨어가 보장하는 증감 연산을 쓴다
공유하지 않는다스레드마다 따로 계산하고 마지막에 합친다
조건부 갱신DB 라면 조건과 갱신을 한 문장으로

흔한 실수: 재현이 어려워 없다고 판단하는 것. 타이밍에 따라 드물게 나타나므로 테스트에서 안 보여도 운영에서 터집니다.

Q.실무에서 세마포어가 사용되는 예시를 들어주세요.

동시에 N개까지만 허용해야 하는 자리입니다.

초기값
DB 커넥션 풀최대 연결 수
외부 API 호출 제한초당 허용 호출 수
파일 다운로드 동시 실행 수대역폭을 고려한 값
무거운 작업의 동시 실행 제한코어 수 안팎
생산자 소비자 큐빈 자리 수와 채워진 수 각각

마지막은 상호 배제가 아니라 신호 전달입니다. 큐가 비었으면 소비자가 기다리고, 생산자가 넣으면 신호를 올려 깨웁니다.

주의할 것은 반납입니다. 예외가 난 경로에서 반납을 빼먹으면 카운트가 한 방향으로만 줄어 결국 모두 멈춥니다. 획득과 반납을 자원 관리 구문으로 묶어야 합니다.

흔한 실수: 세마포어로 상호 배제를 구현하는 것. 동작은 하지만 소유권이 없어 남이 푸는 실수를 못 막습니다. 하나만 통과시켜야 하면 뮤텍스입니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

운영체제 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.