CS/운영체제

[OS] 프로세스 동기화(세마포어와 뮤텍스)

초코chip 2024. 9. 2. 19:57

배경

공유 데이터에 동시에 접근할 때 데이터 일관성에 대한 문제가 발생할 수 있다.

  • 멀티 스레드: 공유 공간
  • 멀티 프로세스: 공유 메모리

다음 C 코드는 pthread 라이브러리를 이용하여 두 개의 스레드를 생성하고, 각 스레드에서 전역 변수 sum에 10,000씩을 더하는 작업을 수행한다. 이론적으로 두 스레드의 작업이 완료된 후 sum의 값은 20,000이 되어야 하지만, 실제로는 이 값이 다르게 나오는 경우가 있다.

image

경쟁 상태(Race Condition)

코드가 예상과 다른 결과를 출력하는 주된 이유는 `sum` 변수에 대한 동시 접근 때문이다. 각 스레드가 `sum++` 연산을 수행할 때, 이 연산은 사실상 세 부분으로 나뉘어 실행된다:

  1. `sum` 변수의 현재 값을 읽는다.
  2. 값을 1 증가시킨다.
  3. 증가된 값을 다시 `sum` 변수에 저장한다.

이 과정에서 스레드 스위칭이 발생할 수 있어, 한 스레드가 `sum` 값을 읽은 뒤, 증가시키기 전에 다른 스레드가 실행되어 같은 초기 값을 읽고 증가시킬 수 있다.

 

그 결과, 두 스레드 모두 같은 값을 기반으로 증가를 하므로 `sum` 값은 실제로 총 증가해야 할 횟수보다 적게 증가할 수 있다.

이렇게 두 개 이상의 스레드가 동시에 공유 자원에 접근할 때 발생하는 문제를 경쟁 상태(Race Condition)라고 한다.

 

Critical Sectoin Problem

개념

임계 영역

  • 정의: 여러 스레드가 동시에 접근할 경우 데이터의 일관성을 해칠 수 있는 공유 자원을 접근하는 코드 영역이다.
    • = Race Condition이 발생할 수 있는 코드 영역
  • 따라서 프로세스 코드는 다음 4가지 영역으로 구분 가능
image

- entry-section: 임계 영역에 접근하기 위한 코드 영역

- critical-section: 임계 영역

- exit-section: 임계 영역에서 나가는 코드 영역

- remainder-section: 나머지 코드 영역

 

CS 문제 해결 방법

locking(열쇠)을 이용해서 처리하는 방법

  • Mutex Lock(뮤텍스): 열쇠가 1개인 것
  • Semaphore(세마포어): 열쇠가 n개인 것

 

Mutex Lock

  • 정의 : 단일 스레드만이 특정 시점에 공유 자원에 접근할 수 있도록 보장하는 락(lock) 메커니즘
  • 방법: lock을 판단하는 boolean 변수를 활용
    • 2개의 atomic 함수가 존재
      • lock : 뮤텍스가 이미 잠겨있지 않다면 잠그고, 잠겨있다면 해제될 때까지 스레드를 대기 상태로 만든다.
      • unlock : 뮤텍스를 해제하여 다른 스레드가 임계 영역에 접근할 수 있도록 한다.
전체 구조 acquire함수 release함수
image image image

image

 

Semaphore

  • 정의 : 여러 스레드가 공유 자원에 접근할 수 있는 동시성을 제어하는 카운팅 메커니즘
  • 방법 : 자원의 접근 가능 수를 나타내는 정수 변수를 활용
    • 2개의 atomic 함수가 존재
      • wait(): 세마포어의 count를 하나 감소시킨다. 만약 count가 0 이하이면 자원이 해제될 때까지 스레드를 대기 상태로 만든다.
      • signal(): 세마포어의 count를 하나 증가시킨다. 이를 통해 대기 중인 스레드 중 하나가 임계 영역에 접근할 수 있도록 하거나, 추가적인 자원 접근을 허용한다.
전체 과정 wait() 함수 signal() 함수
image image image

image

뮤텍스와 세마포어 차이

  • 뮤텍스는 자원을 소유하는 형태로, 뮤텍스를 소유한 스레드만이 락을 해제할 수 있다.
    • 보호된 자원의 일관성이 중요할 때 사용
  • 세마포어는 소유 개념이 없고, 이는 세마포어를 설정한 스레드와 해제하는 스레드가 반드시 동일할 필요가 없다.
    • 자원을 보호하는 것이 아닌, 자원의 사용 순서를 제어하거나 신호를 보내는 데 주로 사용
    • 스레드 간의 작업 순서를 동기화하거나 특정 작업이 끝났음을 알리는 용도

'CS > 운영체제' 카테고리의 다른 글

[OS] 메모리 관리  (0) 2024.09.02
[OS] 데드락  (0) 2024.09.02
[OS] CPU 스케줄링  (1) 2024.09.02
[OS] 스레드  (0) 2024.09.02
[OS] 프로세스간 통신(IPC)  (0) 2024.09.02