728x90
Cooperating processes는 서로 다른 프로세스간에 데이터를 공유하는 등 서로에게 영향이 있기마련이다.
프로세스들이 동시에 shared data에 접근하게 될 때는 데이터가 깨지는 현상도 생길 수 있다.
그래서 cooperation processes 간에 순서를 보장 하는 등 데이터를 잘 보존할 수 있는 체계(?)가 필요하다.
순서를 보장하는 것이 동기화이다. 즉 프로세스 동기화는 프로세스들이 공유하는 자원의 일관성을 유지하는 것이다.
두 개의 프로세스가 shared data에 동시에 접근하게 되었을 때 문제가 발생할 수 있다.
로우 레벨로 접근해보면 두개의 프로세스가 공통 변수에 접근했을 떄 아래와 같이 접근할 수 잇다.
[프로세스 1]
register_1 = count (공통 변수를 count라고 하자)
register_1 = register_1 + 1
count = register_1
[프로세스 2]
register_2 = count (공통 변수를 count라고 하자)
register_2 = register_2 - 1
count = register_2
프로세스 1은 공통변수 count를 1씩 증가시키고 프로세스 2는 count를 1씩 감소시킨다.
이때 프로세스 1이 결과값을 count변수에 넣기 전에 프로세스 2가 시작 된다면 데이터가 깨지는 현상이 발생한다.
어떤 순서로 실행되느냐에 따라서 결과가 달라지게 된다. 공동 변수에 순서에 따라 결과값이 달라지는 상황을 Race Condition이라고 한다.
Race condition으로 부터 보호되기 위해서는 아래의 사항들을 보장해야 한다.
- shared data에 하나의 쓰레드만 접근할 수 있도록 관리해야한다.
(이러한 shared data 구역을 Critical Section, 임계구역이라고 한다)
- 프로세스가 동기화 되어야한다.
✅Race Condition을 해결하기 위한 3가지 충족 조건
- Mutual Exclution
두 개 이상의 프로세스가 공통변수에 동시에 접근하는것을 막기 위한 방식이다.
한 프로세스가 공통 변수에 접근했으면 다른 프로세스가 접근하지 못하도록 flag값을 사용하여 막는 방법이다. 이것을 교착상태(Mutual Exclution)라고 한다. - Progress(avoid deadlock)
임계 영역에 들어간 프로세스가 있지 않은 상태에서 임계역영에 들어가려는 프로세스가 있으면 들어가게 해주어야 한다. - Bounded Waitind(avoid starvation)
starvation 상태를 방지하기 위해서 프로세스가 임계영역에 진입하려고 요청한 후로부터 다른 프로세스들이 임계영역에 진입하려는 횟수에 한계가 있어야 한다. 임계영역에 진입했다가 release 된 프로세스는 다음 진입에 대한 제한을 준다.
✅Race Condition을 예방하는 방법
- Mutex lock
가장 간단한 동기화 툴이다. Mutual Exclution과 같은 방식으로 진행된다. (프로세스가 2개일 때 사용)프로세스가 임계영역에 진입될 때 lock 하는 acquire 함수와 임계영역을 벗어날 때 lock을 푸는 release 함수가 있다.
//메인 함수 while(true) { /*acquire lock!*/ /*critical seiction*/ /*release lock!*/ /*remainder section*/ } //함수 정의 void acquire(){ while(!available){ //busy wait } available = falase; } void release(){ available = true; }Busy wait이란, 임계영역에 진입하려는 다른 모든 프로세스들이 acquire함수 내에서 임계영역 접근이 가능해질 때까지 무한 루프를 돌며 기다리는 것이다. Busy wait은 CPU낭비하는 문제점이 있다. - Semaphore
편리하고 효과적인 동기화 툴이다. (프로세스 n개일 때 사용)
세마포어는 wait(또는 P)와 signal(또는 V) 함수를 통해 공통변수에 접근할 수 있다. 또 뮤텍스와 다르게 boolean값인 available 변수가 아닌 정수형인 S 변수를 사용한다.
wait 함수는 S 값을 감소시키고 만약 S가 0보다 작으면 이미 해당 임계구역에 어느 프로세스가 존재한다는 의미이므로 현재 프로세스는 접근하지 못하도록 한다. 뮤텍스에서의 acquire과 같은 역할이다.//함수 정의 wait(int S){ while(S <= 0){ /*busy wait*/ } S--; } signal(int S){ S++; }
signal은 임계영역에서 나올때 S를 증가시킨다.
세마포어의 로직은 마치 이마트 주차장 전광판과 같다.
S는 임계영역에 접근할 수 있는 프로세스의 갯수이고 S가 0일 경우에는 임계영역 접근 가능한 자리가 나올 때까지 기다려야한다. 그리고 임계영역에서 빠져나온 프로세스가 있을 경우 자리가 비어있다고 S의 값을 증가시켜준다.
세마포어 역시 busy wait이라는 문제에 고착되어 있다. 이를 해결하기 위해 wait과 signal 함수를 수정할 수 있다. S가 0이거나 음수일때 busy wait이 아닌 프로세스를 일시 중단하고 wait queue로 이동시킨다.
어느 프로세스가 signal 함수를 호출했을 때 wait queue에 있는 프로세스가 ready queue로 이동하면 busy wait에 관한 문제를 해결 할 수 있다.
세마포어는 동기화에 편리하고 효과적이지만 타이밍 오류가 발생할 수 있는 문제점이 있다.
이 오류는 항상 발생하는 것도 아니라서 감지하기 어려운 점이 있다.
728x90
'STUDY > 운영체제' 카테고리의 다른 글
| [운영체제] 메인 메모리 (0) | 2022.02.21 |
|---|---|
| [운영체제] 데드락(Dead lock) (0) | 2022.02.13 |
| [운영체제] CPU 스케줄링 (0) | 2022.01.17 |
| [운영체제] 쓰레드 (thread) (0) | 2022.01.10 |
| [운영체제] 프로세스 간의 통신 (IPC) (0) | 2021.12.29 |