소스코드
const int N = 10; // 버퍼의 공간을 잡을 상수
const int TRUE = 1; // TRUE = 1을 나타내는 상수
const int FALSE = 0; // FALSE = 0을 나타내는 상수, 세마포어에서 쓰이지는 않음.
semaphore mutex = 1; //이진 세마포어 를 구현하기위한 세마포어 변수 초기 값을 1로 설정
semaphore empty = N; //빈공간이 얼마만큼 남았는지 계산하는 세마포어 변수 초기 값을 버퍼의 갯수 만큼 설정.
semaphore full = 0; //생산품이 얼마만큼 차있는지 계산하는 세마포어 변수 초기값을 0으로 설정.
int buffer[N]; // 임계구역 공용 변수
void producer(void) // 생산자
{
int item = 1; //생산자가 1이라는 item을 생성함.
int i = 0; //공용번수의 자리번호를 정하기 위함.
int Num; //공용변수 배열에 값을 지정하기 위함. 10까지 지나면 다시 1로 돌아오기 때문에 % //연산을 해야 함.
while(TRUE) //무한 생산
{
wait(empty); //먼저 빈 공간을 할당 받고, 빈공간이 남아있다면 블록 되지않고 통과함
// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;
wait(mutex); //2진 세마포어로 임계구역을 쓰는 프로세스가 있는지를 확인.
//초기값이 1이므로 다른 프로세스가 먼저 사용하지 않았다면 0으로 만들고 진입.
cout<<"Insert item "<<i<<" buffer place"<<endl; //임계구역에 들어왔음을 출력.
cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl; //세마포어 번호
Num = i%N; //나누기 연산자를 쓴 것은 9 다음 카운트로 10이아닌 0으로 돌아가게 하기위 //함. 앞에 test_and_set구현의 이웃 프로세스에게 자리 양보 의 응용.
// if(buffer[Num] == 0)
// {
buffer[Num] = item; // 공용변수에 생산품을 집어넣음
i = (i+1)%N; // 공용변수의 다음 자리로 이동
cout<<"buffer["<<Num<<"] 's insert_item is "<<buffer[Num]<<endl<<endl;
// }
// else
// {
// cout<<"buffer["<<Num<<"] is not empty"<<endl;
// }
//여기서 if else 문을 썼던 것은 %연산자로 인해 환형 큐 형식으로 되어서 만약 공용번수에 모든 값을 집어 넣고
//나서도 또 넣으려고 시도 할 때 예외처리 하려고 했었으나, 이렇게 하지 않아도 empty 와 full 세마포어 로 인해
//블록이 되므로 굳이 쓰지 않아도 됩니다.
signal(mutex); //임계구역을 빠져나감을 알림 mutex값을 +1 증가 시켜주고 신호를 보냄.
// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;
signal(full); //full 값을 증가시켜줌으로 소비자가 임계구역이 비어있지 않다는것을 알림.
}
}
void consumer(void) //소비자
{
int item = 0; //소비자가 소비를 하고나면 원래 초기 빈값을 넣어줌
int i = 0; //공용번수의 자리번호를 정하기 위함.
int Num; // 역시 % 연산자로 인해 연산을 하여 값을 넣어야 하므로 변수를 생성함.
while(TRUE) //무한 소비
{
wait(full); //full 세마포어 변수가 0일시 공용변수가 비어있으므로 소비 할 수 없고 블록 됨.
// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;
wait(mutex); //2진 세마포어로 임계구역을 쓰는 프로세스가 있는지를 확인.
cout<<"Remove item "<<i<<" buffer place"<<endl; //임계구역 진입을 출력함
cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl; //세마포어 번호
Num = i%N; // 위의 생산자에서의 설명과 같이 9 -> 0으로 돌리기 위해 %연산을 함.
// if(buffer[Num] == 1)
// {
buffer[Num] = item; // 소비자가 소비 후 버퍼를 빈상태로 돌림.
i = (i+1)%N; //공용변수의 다음 자리로 이동.
cout<<"buffer["<<Num<<"] 's item remove result is "<<buffer[Num]<<endl<<endl;
// }
// else
// {
// cout<<"No product in"<<"buffer["<<Num<<"]"<<endl;
// }
//여기서 if else문을 썼던겄도 위에 생산자에서의 이유와 동일함.
signal(mutex); //임계구역을 빠져 나감을 알림.
// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;
signal(empty); // 하나를 소비했으므로 빈공간이 한개 더 늘었음을 알려줌.
}
}
void prod(void) //생산자 스레드
{
producer();
}
void consum(void) // 소비자 스레드
{
consumer();
}
void main()
{
int i;
for(i=0; i<N; i=i+1) // 공용변수의 초기화
{
buffer[i] = 0;
}
cobegin // 병행 수행을 하기위한 cobegin문.
{
prod();
consum();
}
}
실행결과 화면

