본문 바로가기
공부/OS

[OS] 프로세스 동기화 문제 (세마포어)

by 웅대 2023. 5. 27.
728x90
반응형

프로세스는 공유 메모리를 사용하여 공통된 변수와 버퍼를 공유한다.

 

그런데 context switching을 통해 현재 cpu를 할당받은 프로세스가 달라지면 공유 메모리에 동시에 접근하는 이슈가 발생할 수 있다.

 

이를 동기화 이슈라고 한다.

 

동기화 이슈

 

예를 들어서 A와 B가 100만원이 들어있는 같은 통장에 10만원씩 예금했다고 해보자.

 

10만원을 예금하는 코드의 구성은 다음과 같다.

 

  1. 통장의 총 금액을 가져온다.
  2. 해당 금액에 10만원을 추가한다.
  3. 추가한 금액을 통장에 저장한다.

멀티 프로세스 환경에서는 프로세스를 동시에 실행할 수 없다보니 두 프로세스를 조금씩 번갈아가면서 실행하게 된다.

 

그런데 다음과 같이 context switching이 발생할 수 있다. (빨간색이 프로세스 A, 초록색이 프로세스 B)

 

1. 통장의 총 금액을 가져온다. (100만원)

2. 해당 금액에 10만원을 추가한다. (110만원)

1. 통장의 총 금액을 가져온다. (100만원)

2. 해당 금액에 10만원을 추가한다. (110만원)

3. 추가한 금액을 통장에 저장한다. (110만원)

3. 추가한 금액을 통장에 저장한다. (110만원)

 

실제로 A와 B는 10만원씩 총 20만원을 예금했는데 실제 통장에는 10만원만 예금이 된 것으로 반영이 되었다.

 

여러 개의 프로세스가 동시에 같은 공유 자원에 접근하다보니 발생한 문제이다.

 

이러한 문제를 동기화 이슈라고 한다.

 

임계 구역(critical section) 문제

임계 구역 (critical section) : 다른 프로세스와 공유하는 변수, 테이블과 같은 부분

 

임곅 구역은 상호배타적(mutually exclusive)이어야 한다.

 

이 말은 곧 한 프로세스가 임계 구역에 진입한 상태라면 다른 프로세스의 진입을 막아야 한다.

 

그래서 다음과 같이 진입 허가 요청하는 진입 구역(entry section)과 임계 구역을 빠져나온다는 출구 구역(exit section)이 존재한다.

 

entry section (임계 구역 진입 허가 요청)

critical section (임계 구역)

exit section (임계 구역 빠져나옴)

remainder section (잔류 구역)

 

이러한 임계 구역 문제를 해결할 때 세 가지 조건이 필요하다.

 

  1. 상호 배제 (mutual exclusive) : 임계 구역에는 동시에 여러 프로세스가 접근할 수 없다.
  2. 진행 (progress) : 임계 구역에 여러 프로세스가 접근하려고 할 때 진입 순서는 프로세스들에 의해서 결정되고 계속 접근하지 못하는 프로세스가 존재해서는 안된다.
  3. 한계 대기 (bounded waitinig) : 프로세스가 임계 구역에 접근 요청을 하면 요청 허용 전까지 다른 프로세스의 임계 구역 진입 횟수가 제한되어야 한다.

 

세마포어(Semaphore)

세마포어의 뜻은 두 개의 원자적 함수로 조작되는 정수 변수이다.

 

우선 세마포어는 "정수 변수"이다.

 

예를 들어서 공유 메모리에 3개의 프로세스까지 접근할 수 있다고 하자.

 

그러면 세마포어의 초기값은 3이 될 것이고 0 또는 음수라는 뜻은 더이상 프로세스가 임계 구역에 접근할 수 없다는 뜻이다.

 

세마포어의 예시로 화장실 키를 들곤 한다.

 

화장실 키가 총 3개가 있다고 하면 화장실에 갈 때 키를 하나 가지고 간다. (Semaphore --)

 

일을 보고 나면 키를 반납한다. (Semaphore ++)

 

키가 없다면 (if Semaphore<=0) 키가 생길 때까지 기다린다.

 

그리고 이 세마포어의 값을 변경할 수 있는 함수는 Wait과 Signal 두 개이다.

 

<Wait>

wait(S){
    while(S<=0);
    S--;
}

임계 구역에 들어갈 수 있는 자리가 날 때까지 기다린다.

 

<Signal>

signal(S){
    S++;
}

임계 구역에 접근해서 할 일이 모두 끝났다면 다른 프로세스가 임계 구역에 접근할 수 있게끔 세마포어의 값을 늘려준다.

 

이 Wait과 Signal 함수는 원자적(atomic)이어야 한다.

 

즉 두 함수는 한 번 실행한다면 반드시  중간에 멈추는 일 없이 함수를 마쳐야 한다.

 

이를 코드에 적용한 코드는 다음과 같다. S가 처음에는 1로 초기화 된다고 가정하자.

do{
    wait(S)
    critical section
    signal(S)
    remainder section
}

 

728x90
반응형

댓글