
Shared data
- buffer 자체 및 buffer 조작 변수(empty/full buffer의 시작 위치)
버퍼의 크기가 유한함!
생산자 프로세스와 소비자 프로세스가 각각 여러개 존재한다.
생산자는 공유버퍼에 데이터를 생성해서 집어넣는 역할을 한다. 주황색은 데이터가 채워진 상태
- 이때 발생할 수 있는 synchronization문제는 두 개의 생산자가 하나의 버퍼에 동시에 데이터를 집어넣는 경우에 발생한다. 이런 문제는 위의 사진에 나와있는대로 lock/unlock 방식으로 방지할 수 있다.
소비자는 버퍼에서 데이터를 꺼내가서 사용한다.
- 이때 발생할 수 있는 synchronization문제는 두 개의 소비자가 하나의 버퍼에 있는 데이터를 꺼내갈려고 할 때 발생할 수 있는데, 그러한 경우에도 위에있는 사진처럼 lock/unlock 방식으로 하면된다.
mutual exclusion(상호배제) : shared data의 mutual exclusion을 위해 semaphore변수가 필요함(lock을 걸기위한 값)
resouce count : 남은 full/empty buffer의 수를 표시하기 위해 semaphore변수가 필요함

Producer
- P(empty) - 빈 버퍼가 있는지 확인, 없다면 기다림
- P(mutex) - 버퍼에 데이터를 넣기위해 버퍼에 lock을 건다
- V(mutex) - 버퍼에 걸었던 lock을 푼다
- V(full) - 내용이 들어있는 버퍼의 개수를 1 증가시킴
Consumer
- P(pull) - 내용이 들어있는 버퍼가 있는지 확인, 없다면 기다림
- P(mutex) - 버퍼에 데이터를 넣기위해 버퍼에 lock을 건다
- V(mutex) - 버퍼에 걸었던 lock을 푼다
- V(empty) - 비어있는 버퍼의 개수를 1 증가시킴
프로세스는 2 종류가 있다. 읽는 프로세스와 쓰는 프로세스가 있음

Writer
- DB는 데이터 그 자체이고, db는 DB에 대한 semaphore에 해당
- P(db) : 공유데이터에 lock을 걸어 다른 프로세스가 접근못하게 하기
- V(db) : lock을 풀어줌
Reader
- 읽을때 lock을 걸긴해야한다. 이건 다른 reader를 막기위한 장치가 아니라 writer가 접근하지 못하도록 하기위해서!!
- P(mutex) : readcount가 공유변수이기 때문에 두개의 reader가 동시에 들어오게 되면 readcount가 제대로 증가되지 않을 수 있기때문에 우선 lock을 건다. readcount를 1 증가시키고 V(mutex)를 실행해서 lock을 푼다.
(식사하는 철학자 문제)

5 명의 철학자는
1. 밥을 먹거나,
2. 생각을 한다.
밥을 먹을때는 자신의 양 옆에있는 젓가락을 사용해서 밥을 먹을 수 있고,
생각을 할 때는 젓가락을 내려놓는다.


모니터는 공유데이터를 모니터 내부에 선언해놓고,
공유데이터에 접근하기 위해서는 모니터 내부의 프로시저를통해서만 내부데이터에 접근할 수 있게 해놓음
모니터는 원천적으로 동시에 여러 프로세스가 접근이 안되도록 한다! 그래서 lock을 걸 필요가 없다! 다른 프로세스들은 모니터 외부에서 줄서서 기다린다.
모니터 내에서는 한번에 하나의 프로세스만이 활동 가능
프로그래머가 동기화 제약조건을 명시적으로 코딩할 필요가 없음
프로세스가 모니터 안에서 기다릴 수 있도록 하기위해 condition variable 사용 condition x, y
condition variable은 wait 와 signal 연산에 의해서만 접근 가능
- x.wait(); : w.wait을 invoke한 프로세스는 다른 프로세스가 x.signal()을 invoke 하기전까지 suspend 된다.
-x.signal(); : x.signal()은 정확하게 하나의 suspend 된 프로세스를 resume 한다. suspend된 프로세스가 없으면 아무일도 일어나지 않는다.
아까 위에서 봤던 생산자-소비자 문제의 semaphore 코드를 monitor 코드로 변환한것

공유 버퍼가 모니터 안에 정의되어 있음
생산자, 소비자 함수가 모니터 내부에 정의되어 있다.
여기서 signal 연산이 하는 역할은
대기중인 프로세스를 깨워?주는 역할!
void produce
이 함수의 내부 코드를 보면
만약 비어있는 버퍼가 있다면 버퍼에 x 값을 넣고 full에 신호를 준다. 그런데 만약 비어있는 버퍼가 없다면 empty에서 기다린다.
void consume
위의 함수와 반대로 동작한다.
만약 값이 채워져있는 버퍼가 있다면 버퍼에 x 값을 빼서 소비한다. 그리고 empty에 신호를 준다.
그런데 값이 채워져있는 버퍼가 없다면 full에서 기다린다.
semaphore변수를 사용하는 코드에서는 lock/unlock을 해주는 코드가 있었지만 monitor 코드에서는 별도로 두지 않아도 된다.