프로세스 동기화

2020. 9. 11. 15:07OS

동기화라는 것은 같은 시간에 메모리를 read와 write가 동시에 발생하면 데이터가 일치하지 않게 될것이다. 동시에 여러 개의 프로세스가 동일한 자료를 접근해 조작하고, 그 실행 결과가 접근이 발생한 특정 순서에 의존하는 상황을 경쟁상황이라고 한다. 이렇듯 자원에 다수의 프로세스가 접근해서 사용한 후에도 데이터가 올바르게 유지하는 것을 프로세스 동기화라고한다. 

 

임계구역 문제

각 프로세스는 일반적으로 아래와 같은 구조를 이룬다. 

 

프로세스의 일반적인 구조

각 프로세스는 임계구역이라고 부르는 코드부분을 갖고 있고 이 안에서 공유 변수를 바꾸거나 테이블을 갱신하거나 파일을 쓰거나 하는 등의 작업을 수행한다. 여기서 중요한 점은 한 프로세스가 임계구역을 사용하고 있다면 다른 프로세스는 접근하지 못한다. 각 프로세스는 임계구역에 들어가기 위해서는 진입 구역에서 확인을 통해서 들어갈 수 있다. 

 

 

임계구역 문제를 해결안은 밑의 3가지 요구를 충족해야한다. 

 

  • 상호 배제

    하나의 프로세스가 임계구역에서 실행되고 있으면 다른 프로세스는 임계구역에서 실행될 수 없다.

  • 진행

    임계구역에서 실행 중인 프로세스가 없다면, 임계구역으로 진입하고 싶어하는 프로세스들 중에 적절히 골라서 허용해야한다. 
  • 한정된 대기

    하나의 프로세스가 임계구역에 너무 오래 머무르게 되면 다른 프로세스들이 접근할 수 없습니다. 이러한 기아현상을 막기위해서 한번 임계구역에 들어간 프로세스는 다음 번에 들어갈 때는 제한을 두어야합니다.

 

일반적으로 임계구역을 다루는데는 선점형 커널과 비선점형 커널 접근법이 사용된다. 

 

  • 선점형 커널

    프로세스가 커널 모드에서 실행될 때 선점되는 것을 허용한다.

  • 비선점형 커널

    커널을 빠져나갈 때까지 또는 봉쇄될 때 까지 자발적으로 CPU의 제어를 양보할 때까지 계속 수행된다. 

피터슨의 해결안

두 프로세스가 두 개의 데이터 항목을 공유하도록 하여 해결한다.

 

turn: 임계구역에 진입할 순번을 나타낸다.

 

flag: 임계구역에 들어갈 준비가 완료되었음을 의미한다. flag[i]가 true이면 i가 들어갈 준비완료되었음을 의미한다. 

 

 

해당 코드를 설명하면

 

flag[i] = true;는 현재 i프로세스가 임계구역에 들어갈 준비가 완료되었음을 의미한다. 

turn = j; 현재 프로세스 j가 실행될 차례임을 의미한다. 

 

while(flag[j] && turn == j) 무한루프에 걸려서 다른 프로세스들이 접근하지 못한다. 

 

flag[j] = false; j의 작업이 종료된 후 false로 바껴서 무한루프문이 종료된다. 즉 다른 프로세들도 접근할 수 있다. 

 

동기화 하드웨어

이전에는 소프트웨어에 대해 알아보았다면 이번에는 하드웨어는 어떻게 처리할까 알아보자!

 

test and set
test_and_set()을 사용한 상호배제 구현

초기에 lock은 false로 초기화되어있다. false이기 때문에 초기 한개의 프로세스를 임계구역에 넘겨준 후 test_and_set에 의해 lock은 true가 된다. true로 변형 후 무한 루프문에 빠져서 임계구역에 있는 프로세스가 종료될 때까지 무한루프가 된다. 

 

여기서 중요한 특징은 atomic인데 인터럽트 되지않는  명령어 몇개의 줄이든 결국 한개의 명령어로 보는 것이다. 

 

Mutex Locks

하드웨어의 해결책의 경우에는 복잡할 뿐만 아니라 응용프로그래머는 사용할 수 없다. 간단하게 사용하기 위한 간단한 도구는 mutex 락이다. 

 

acquire()

함수가 lock을 획득합니다. acquire를 통해 락을 얻어서 다른 프로세스들이 못오도록 막은 후

 

release()

함수가 lock을 반환합니다.  종료되면 release를 통해 lock을 반환해 다른 프로세스가 접근할 수 있게 만듭니다.

 

두 함수는 원자적으로 수행되어야한다. 

 

release와 acquire

 

이전까지의 경우에는 busy waiting이 필요하는 것이 단점이었습니다. 락이 가용해지기를 기다리면서 프로세스가 계속 회전을 하고 있기 때문에 spinlock이라고  부른다. spinlock의 경우에는 test and set과 compare and swap과 같은 상당한 시간을 소모하ㅓ는 문맥교환이 전혀 필요로하지 않는 것이 spinlock의 장점이다.

 

*busy waiting: 계속해서 임계구역으로 접근할 수 있는지 무한루프를 돌면서 조건문을 체크하는 방법.

 

세마포어

atoma 함수인 Wait과 Signal을 제공한다. 이는 중요한 사항이다. 두 프로세스가 동시에 wait과 signal 연산들을 실행할 수 없도록 반드시 보장해야한다. 

 

Wait은 일반적으로 검사를 진행하고 네덜란드어 Proberen에서 P, Signal의 경우에는 수를 증가시키는데 네덜란드어인 Verhogen의 V라고 지었다. 

 

이진 세마포어

0과 1 두가지 값을 사용해서 세마포어를 구현한다. 0이면 지나갈 수 있고 1이면 지나갈 수 없다. 즉 Mutex Lock과는 비슷하다. 

 

counting 세마포어

n개의 자원을 locking하는 방법 하나의 자원을 사용하면 n-1, 두개 사용하면 n-2 이런식으로 0이 될 때 까지 자원할당 가능.

 

초기에 가용 가능한 자원의 개수로 초기화를 진행 후 0이 될때 까지 줄어나간다. 0이 되면 더 이상 할당 가능한 자원이 없기 때문에 무한 루프에 빠지는 것이다. 

 

 

'OS' 카테고리의 다른 글

교착 상태 (추후 추가 필요)  (0) 2020.09.13
CPU 스케줄링  (0) 2020.09.09
스레드  (0) 2020.09.07
컴퓨터 OS 프로세스  (0) 2020.09.05
Thread Context Switching vs Process Context Switching  (1) 2020.05.05