포스트

임베디드 스터디 - 상호배제

임베디드 스터디 - 상호배제

임계 영역과 상호배제

  • 두 프로세스가 동시에 같은 변수를 수정하면 레이스 컨디션이 발생함
  • 한 번에 하나의 프로세스만 접근할 수 있는 구간을 임계 영역(Critical Section) 이라고 함
  • 임계 영역을 보호하는 메커니즘을 상호배제(Mutual Exclusion) 라고 함

spinlock

  • 임계 영역 진입을 기다릴 때 Busy wait 방식으로 락을 확인함
1
2
while (lock 잠겨있음) { /* 계속 확인 */ }
// 진입 성공
  • 장점 : 컨텍스트 스위치 오버헤드 없음 → 대기 시간이 짧을 때 유리
  • 단점 : Busy wait → CPU 낭비, 다른 작업 불가
  • sleep이 불가능한 인터럽트 컨텍스트에서 사용할 수 있는 유일한 락

mutex

  • 임계 영역이 잠겨있을 때 프로세스를 SLEEP 시키고 대기, 해제되면 WAKE UP
1
2
3
4
mutex_lock(&lock);
// 잠겨있으면 → 프로세스를 SLEEP시키고 대기
// 해제되면  → WAKE UP 후 진입
mutex_unlock(&lock);
  • 한 번에 한 개 프로세스만 진입 가능
  • 임계 영역이 길 때 (파일 I/O, 네트워크 처리 등) spinlock보다 유리
  • 인터럽트 컨텍스트에서는 사용 불가 (sleep이 불가능하기 때문)

세마포어 (Semaphore)

  • 한 번에 여러 개 프로세스까지 임계 영역 진입을 허용
    • mutex는 N=1인 세마포어로 볼 수 있음
  • 예시 : 프린터 3대 → 세마포어를 3으로 설정하면 동시에 3개 프로세스까지 접근 가능
  • sleep 기반 대기 → 인터럽트 컨텍스트에서 사용 불가

rwlock

  • 읽기(read)와 쓰기(write) 접근을 구분하는 락
1
2
읽기(read)  : 데이터를 바꾸지 않으므로 여러 프로세스가 동시에 접근 가능
쓰기(write) : 데이터를 바꾸므로 반드시 혼자만 접근해야 함
1
2
read_lock()  // 읽기 락 → 다른 읽기와 동시 진입 허용
write_lock() // 쓰기 락 → 읽기·쓰기 모두 배제, 혼자만 진입
  • 읽기가 빈번하고 쓰기가 드문 구조에서 효율적
    • 예) 센서 데이터를 여러 스레드가 읽고, 하나의 스레드가 주기적으로 업데이트

비교 요약

 sleep 가능동시 진입 수인터럽트 컨텍스트
spinlock1개
mutex1개
semaphore여러 개
rwlock읽기 N개 / 쓰기 1개
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.