5.2 공유자원과 임계구역
5.2.1 공유자원
공유자원은 여러 프로세스가 공동으로 이용하는 변수/메모리/파일등이다. 해당 자원은 병렬로 처리되는 여러 프로세스들이 같이 사용하므로, 어떤 프로세스가 언제 데이터를 읽고 쓰는지에 따라 그 결과가 달라진다.
5.2.2 임계구역
공유 자원에 접근하는 순서에 따라 실행의 결과 달라지는 프로그램(코드)의 여역을 임계구역이라고 한다. 이러한 임계구역에서는 프로세스들이 동시에 작업하면 안된다.
5.2.4 임계구역 해결 조건
- 상호배제(mutual exclusion) : 임계구역내의 프로세스는 하나여야한다.
- 한정대기(bounded waiting) : 임계구역에 진입하지 못하는 프로세스가 있어서는 안된다.
- 진행 융통성(progress flexibility) : A프로세스와 B프로세스 임계구역에 접근할때 그 순서(A->B->A->B…)가 정해져 있는게 아니라, 빨리 처리된 프로세스가 먼저 임계구역에 들어가는것…(A->A->A->B->A->A->B…)
5.3 임계구역 해결 방법
가장 기본적인 해결책은 잠금장치를 만드는것이다. 임계구역 진입시 잠그고, 끝나면 잠금을 풀고 동기화 신호를 보낸다.
5.3.2 임계구역 해결 조건을 고려한 코드 설계
5.3.2.1 상호배제 문제가 발생하는 코드
P1에서 반복문(바쁜대기)를 지났지만 공유변수인 lock을 사용중(true)로 바꾸기 전에 timeout이 발생한 상황. 결국 P1이 임계구역에 들어온 상태에서 P2프로세스도 임계구역으로 진입하게 되어 문제가 발생한다. -> 차단막 다음에 lock을 변경해서 문제가 발생.
- while문과 lock을 true로 만드는 문이 분리되지 않아야한다.
- 바쁜 대기로 인해 자원이 낭비된다.
5.3.2.2 한정 대기 문제가 발생하는 코드
P1진행 중 lock1(P1이 잠금을 걸었는지)을 잠근 다음 timeout1이발생한다. 그리고 P2도 lock2를 잠근다음 timeout2가 발생한다.
- lock1과 lock2 전부 잠긴상태여서 한정 대기조건을 보장하지 못하는 교착상태에 빠진다.
- 프로세스가 증가할때마다 lock변수의 개수도 증가시켜야 하므로 확장성도 떨어진다.
- 바쁜대기로 인한 자원 낭비가 남아있다.
5.3.2.3 진행 융통성 문제가 발생하는 코드
잠금을 확인하는 문장이 하나이므로 상호배제와 한정대기를 보장한다.
- 하지만 P1->P2->P1->P2의 순서가 강제된다(진행의 융통성 조건 보장 안함).
- 바쁜대기 문제는 여전하다.
5.4 하드웨어적인 해결방법
하드웨어의 도움을 받아서, lock상태를 변형하는 코드와 대기하는 코드를 동시에 실행되게 만드는 방식. 그러나 바쁜대기로 인한 자원 낭비는 여전하다.
5.5 세마포어
세마포어 : 초기화를 제외하고, 두 개(P, V)의 원자적(중간에 안끊김) 함수로 조작되는 정수 변수. 세마포어 알고리즘은 이 세마포어를 다루는 방법이다.
- Semaphore(n) : 공유되는 전역변수 RS(세마포어)를 n(가용한 자원개수)로 초기화 한다.
- P() : 잠금을 수행하는 원자적인 함수. 가용한 자원이 있으면 RS를 1 줄이고(자원 하나 씀) 임계구역으로 진입한다. 가용한 자원이 없으면 대기(block)시킨다.
- V() : 잠금 해제 밎 동기화를 같이 수행하는 원자적인 함수. RS를 1 늘리고(자원 하나 복구) 동기화신호인 wake_up을 통해 대기중인 프로세스가 임계상태에 진입하게 한다.
세마포어 잠금이 해제되길 기다리는 프로세스는 세마포어의 큐에 저장되어있다가 wake_up 신호를 받으면 큐에서 나와 임계구역에 진입한다. -> 바쁜대기를 하는 프로세스가 없다.
근데 이렇게 동작되러면… 운영체제의 도움이 있어야할거같은데?
5.6 모니터
세마포어를 잘못사용하는 경우를 방지하기 위해 공뮤자원 및 세마포머를 숨기고, 이를 사용할 인터페이스만 제공하는 것. 임계구역 보호 및 동기화를 위해 내부적으로 상태변수를 사용한다. 이 상태변수는 wait()와 signal()이 있다. 사용자 입장에서는 increase()만 호출하면 된다…라고 쓰여져 있음
근데 이거 책이랑 검색이랑 좀 다른데…
참고하면 좋을곳 : Splin 블로그