Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- mongoose
- nestjs
- react
- Bull
- cookie
- jest
- AWS
- JavaScript
- 게임
- OCR
- Sequelize
- Express
- class
- flask
- game
- GIT
- Queue
- 공룡게임
- 자료구조
- nodejs
- MySQL
- Dinosaur
- TypeScript
- dfs
- MongoDB
- 정렬
- Python
- typeORM
- Nest.js
Archives
- Today
- Total
포시코딩
[운영체제] 5. Process Synchronization (4) - semaphore를 통한 동시성 문제 해결 방법, monitor 본문
CS (Computer Science)
[운영체제] 5. Process Synchronization (4) - semaphore를 통한 동시성 문제 해결 방법, monitor
포시 2023. 5. 5. 23:42728x90
키워드
semaphore, synchronization, bounded-buffer problem, producer-consumer problem,
readers and writers problem, dining-philosophers problem, monitor
Classical Problems of Synchronization
- Bounded-Buffer Problem(Producer-Consumer Problem)
- Readers and Writers Problem
- Dining-Philosophers Problem
Bounded-Buffer Problem
(=Producer-Consumer Problem)
- Buffer: 임시로 데이터를 저장하는 공간
- Buffer의 크기가 유한한 환경에서의 생산자-소비자 문제
- 두가지 프로세스 종류
- Producer: 생산자 프로세스
-> 공유 buffer에 데이터를 만들어 집어넣는 역할(그림상에서 주황색으로 producer가 데이터를 집어넣음) - Consumer: 소비자 프로세스
- 하나씩만 있는게 아닌 여러 개 존재
- Producer: 생산자 프로세스
공유 데이터 관련 synchronization 문제
- 생산자가 둘이 동시에 도착해서 비어있는 buffer에 동시에 데이터를 만들어 집어넣을 경우 문제 발생
-> 공유 buffer에 lock을 걸어 다른 프로세스들의 접근을 막은 후 작업 진행 - 소비자도 마찬가지
buffer가 유한하기 때문에 생기는 문제
- Producer
- buffer가 다 찬 상태에서 producer가 계속 도착해 데이터를 생성하려 하면
producer 입장에선 사용할 수 있는 자원이 없는 상황 발생
-> consumer가 꺼내가야 생성 가능하기 때문에 기다리게 됨 - 비어있는 buffer의 개수가 producer의 자원
- buffer가 다 찬 상태에서 producer가 계속 도착해 데이터를 생성하려 하면
- Consumer
- 내용이 들어있는 buffer의 개수가 consumer의 자원
- producer와 반대로 꺼내갈 자원이 하나도 없을 경우
생산자 프로세스(producer)가 데이터를 만들어 집어넣어 줄 때까지 기다리게 됨
Semaphore를 이용해 해야할 업무 두가지
- lock/unlock 용도
- 둘이 동시에 공유 buffer에 접근하는 것을 막기 위해 공유 buffer 전체에 lock을 걸고,
본인 혼자 베타적으로 접근하게 하고 접근이 끝날 경우 lock을 푸는 문제를 위해 필요
- 둘이 동시에 공유 buffer에 접근하는 것을 막기 위해 공유 buffer 전체에 lock을 걸고,
- 자원의 개수를 세는 용도
- buffer가 가득 차거나 또는 비었을 때, producer 혹은 consumer에게 있어
가용자원을 세는 counting semaphore 변수 필요 - producer 입장에서는 비어있는 buffer의 개수가 자원
- consumer 입장에서는 내용이 들어있는 buffer의 개수가 자원
- buffer가 가득 차거나 또는 비었을 때, producer 혹은 consumer에게 있어
Pseudocode(수도코드)
semaphore 변수
- full: 내용이 들어있는 buffer의 개수를 세기 위한 변수
- empty: 비어있는 buffer를 세기 위한 변수. 처음엔 모두 비어있을테니 default=n
- mutex: lock을 걸기 위한 변수
Readers and Writers Problem
- 읽는 프로세스, 쓰는 프로세스 두 종류가 존재
- 공유 데이터를 DB라 명명
- write(내용을 쓰는 작업)는 동시에 여럿이 하면 안되지만
read(읽는 작업)는 동시에 여럿이 해도 synchronization 관련 아무 문제도 발생하지 않음 - 때문에 P연산, V연산을 매번 걸면서 작업해도 무방하지만
read에 대해서 lock을 거는 행위가 비효율적이게 됨 - 따라서, write 하는 동안엔 lock을 걸어 아무도 DB에 접근하지 못하게 하지만
read중일 경우엔 같이 읽을 수 있게 해주는게 Readers and Writers Problem에서 풀어야 할 과제가 된다.
Pseudocode(수도코드)
- reader의 경우 위에서 말한 내용 때문에 lock을 아예 안걸어도 되는줄 알았겠지만
writer가 lock이 안걸려있으니 와서 lock을 걸고 써버리는 가능성이 있기 때문에
lock을 걸긴 해야함 - readcount 변수(공유 변수 중 하나)를 둬서 lock을 관리
- 최초의 reader일 경우(아무도 읽고 있지 않았던 경우) DB에 lock을 걺
- 최초의 reader가 아니라면(누군가 DB에서 읽고 있는 상황일 경우)
이미 lock이 걸려있기 때문에 DB를 읽기만하면 됨 - 하지만 readcount도 공유 변수기 때문에 그냥 증가시킬 경우 문제가 발생할 수 있음
여러 reader가 동시에 와서 증가시킬 경우 제대로 증가가 안될 수 있기 때문 - 그래서 readcount를 바꾸기 위해서도 공유 변수에 대해서도 lock을 걸 필요가 있음
-> readcount라는 공유 변수를 위한 lock이 mutex라는 semaphore 변수이다.
-> 그림상의 P(mutex), V(mutex) - 마지막에 읽는 프로세스라면 lock을 풀어줘야함
- Shared data(공유 데이터)
- DB 자체
- readcount: 현재 DB에 접근 중인 Reader의 수
- Synchronization variables(공유 변수)
- mutex: readcount를 접근하는 코드(critical section)의 mutual exclusion 보장을 위해 사용
- db: reader와 writer가 공유 DB 자체를 올바르게 접근하게 하는 역할
- Starvation 문제가 발생할 수 있다.
- reader가 도착하고 writer가 도착했을 때, writer는 기다리겠지만
reader는 동시에 읽기가 가능하기 때문에 새롭게 도착하는 reader들이 추가로 읽기 시작하고
그만큼 writer는 더 기다리게 될 것이다.
만약, 이게 반복된다면 writer는 영원히 기다려야 하는 문제가 발생한다. - 그렇다고 writer를 먼저 접근하게 하기엔 여러 개의 reader가 기다리는 상황이 발생하여 비효율적이게 될 가능성 존재
- 그럼 어떻게 함?
-> 이전에 배웠던 큐에 우선순위를 두는 방법 등을 통해 해결할 수 있겠다. - ex) 신호등을 생각.
신호가 없을 경우 차가 계속 지나가서 영원히 건너갈 수 없는 상황이 생기지만
신호가 있다면 언젠가 내 차례가 올 수 있음
Dining-Philosophers Problem
(=식사하는 철학자 문제)
- 철학자들은 생각하는 일, 밥 먹는 일 두가지를 원탁에 앉아 진행
- 간단하게 생각=쉼, 밥=양 쪽의 젓가락을 잡고 식사라고 생각하면 됨
- 철학자들은 생각하거나 밥을 먹는 일을 무한 반복
위 solution의 문제점
- Deadlock의 가능성 존재
- 모든 철학자가 동시에 왼쪽 젓가락을 잡을 경우
- 해결방안
- 철학자가 밥을 먹을 때만 테이블에 앉게 하기
- 4명의 철학자만 테이블에 동시에 앉을 수 있게 하기
- 젓가락을 양쪽 모두 잡을 수 있을 때만 젓가락을 잡을 수 있게 하기(-> 아래 코드 참고)
- 비대칭 - 짝수 철학자는 왼쪽 젓가락부터, 홀수 철학자는 오른쪽 젓가락부터 잡게 하기
Pseudocode(수도코드)
enum {thinking, hungry, eating} state[5]; // 다섯명의 상태(생각중, 배고픔, 먹는중)
semaphore self[5]=0; // 젓가락을 잡을 수 있는 상태(0:가능, 1:불가능)
semaphore mutex=1; // 철학자의 상태가 공유 변수라 다른 철학자가 바꿀 수 있기 때문에 lock을 나타내는 변수
void test(int i) {
if (
state[(i+4)%5] != eating // 내 왼쪽이 식사중이 아닐 경우
&& state[i] == hungry // 내가 배고플 경우
&& state[(i+1)%5] != eating // 내 오른쪽이 식사중이 아닐 경우
) {
state[i] = eating;
V(self[i]); // 위 조건을 만족할 때 나한테 젓가락을 잡을 수 있는 권한을 줌, 0 -> 1
}
}
- 헷갈릴 수 있는 부분
- semaphore는 원래 자원의 개수를 세기 때문에 초기 값을 두는데
위의 코드에선 젓가락을 얻을 수 있는 권한의 목적으로 사용되어 semaphore의 철학에 맞지 않는 코드가 되는 부분이 있음 - -> 추후 나올 monitor 코드를 보면 왜 이렇게 코딩했는지 알 수 있음!
- semaphore는 원래 자원의 개수를 세기 때문에 초기 값을 두는데
Monitor
Semaphore의 문제점
- 프로그래머한테 P 연산, V 연산을 통해 코딩을 비교적 쉽게 만들긴 했지만
그럼에도 불구하고 문제가 생겼을 때 버그를 잡기가 쉽지 않음
한 번의 실수가 모든 시스템에 치명적인 영향을 미칠 수 있다.- V 연산 -> P 연산: Mutual exclusion 깨짐
- P 연산 -> P 연산: Deadlock
- 때문에 Monitor라는 것을 synchronization에서 제공
Monitor란?
- 프로그래밍 언어 차원에서 synchronization을 해결하는.
즉, 동시 수행중인 프로세스 사이에서 abstract data type의 안전한 공유를 보장하기 위한
high-level synchronization construct - 어떤 공유 데이터에 접근하기 위해서는
monitor라고 정의된 내부의 프로시저를 통해서만 공유 데이터만 접근할 수 있게 만들어놓음
- monitor는 원천적으로 monitor 내부의 프로시저가 동시에 여러 개가 실행되지 않게 통제 권한을 줌
쉽게 말하면 monitor에 대한 동시 접근을 허락하지 않는다.
-> 프로그래머는 lock을 걸 필요가 없어짐(semaphore와의 가장 큰 차이) - 하나의 프로세스만 모니터를 접근 가능(나머지 프로세스는 줄서서 대기)
- semaphore에서 자원의 개수를 세는 semaphore 변수 같은 용도의
condition variable 사용. ex) condition x, y; - condition variable은 wait과 signal 연산에 의해서만 접근 가능
- 공유 buffer가 내부에 정의되어 있다.
- produce(생산), consume(소비) 코드를 실행하려면 내부 코드를 실행해야 하고
이로인해 둘 중 하나의 프로세스만 모니터 안에서 활성화 되기 때문에 굳이 lock을 걸지 않아도
synchronizatioin 문제를 고려할 필요가 없어진다.
728x90
'CS (Computer Science)' 카테고리의 다른 글
[운영체제] 6. Deadlock (0) | 2023.05.09 |
---|---|
[운영체제] 5. Process Synchronization (5) - 정리 + monitor (0) | 2023.05.08 |
[운영체제] 5. Process Synchronization (3) (0) | 2023.05.05 |
[운영체제] 5. Process Synchronization (2) - The Critical Section Problem (0) | 2023.05.05 |
[운영체제] 5. Process Synchronization (1) (0) | 2023.05.01 |