Write a C program to simulate the description below using se
Write a C program to simulate the description below using semaphores to synchronize the processes/threads.
A group of fraternity brother and sorority sisters is having a party and drinking from a large communal keg that can hold N servings of soda. When a partier wants to drink, he or she fills a cup from keg, unless it is empty. If the keg is empty, the partier wakes up the pledge and then waits until the pledge has returned with a new keg.
Solution
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<semaphore.h>
#include<signal.h>
#define MAX 10
//Keg which holds no of servings
int N = MAX;
int brothers,sisters,i=0;
int Bservings,Sservings;
void pledge(int signo);
int main()
{
int pidb,pids;
signal( SIGUSR1, pledge ); //instal signal handler
//for semaphore declaration
int sem_id,j; /* semid of semaphore set */
key_t key = 1234; /* key to pass to semget() */
int nsems = 1; /* nsems to pass to semget() */
//for semaphore operation
struct sembuf sop;
sem_id=semget(key,nsems,IPC_CREAT|0666);
printf(\"No of brothers = \");
scanf(\"%d\",&brothers);
printf(\"No of sisters = \");
scanf(\"%d\",&sisters);
//create no of brothers
while(brothers)
{
pidb = fork();
if( pidb > 0 )
{
printf(\"Parent process\ \");
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
kill(getpid(),SIGUSR1);
for(j=0; j<sisters+brothers; j++)
{
wait(NULL);
printf(\"Got %d done \ \", j+1 );
}
//wait(pidb);
}
else
{
printf(\"Brother%d created\ \",++i);
sop.sem_num = 0;
sop.sem_op = 1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
printf(\"N in Brother%d= %d\ \",i,N);
if( N >=0 && Bservings<= N)
{
++Bservings;
N-=Bservings;
printf(\"N = %d\ \",N);
printf(\"Servings = %d\ \",Bservings);
printf(\"Brother%d has taken %d servings\ \",i,Bservings);
}
else
{
printf(\"Brorhes else\ \");
kill(getpid(),SIGUSR1);
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
}
}
--brothers;
}
//create no of brothers
i = 0;
while(sisters)
{
pids = fork();
if( pidb > 0 )
{
printf(\"Parent process\ \");
for(j=0; j<sisters+brothers; j++)
{
wait(NULL);
printf(\"Got %d done \ \", j+1 );
}
//wait(pids);
}
else
{
printf(\"Sisters%d created\ \",++i);
sop.sem_num = 0;
sop.sem_op = 1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
printf(\"N in Sister%d= %d\ \",i,N);
if( N >=0 && Sservings<= N)
{
++Sservings;
N-=Sservings;
printf(\"N = %d\ \",N);
printf(\"Servings = %d\ \",Sservings);
printf(\"Brother%d has taken %d servings\ \",i,Sservings);
}
else
{
printf(\"sisters else\ \");
kill(getpid(),SIGUSR1);
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
}
}
--sisters;
}
}
//if empty execute pledge
void pledge(int signo)
{
//for semaphore operation
struct sembuf sop;
int sem_id; /* semid of semaphore set */
key_t key = 1234; /* key to pass to semget() */
int nsems = 1; /* nsems to pass to semget() */
sem_id=semget(key,nsems,0666);
if (signo == SIGUSR1)
printf(\"received SIGUSR1\ \");
else if (signo == SIGKILL)
printf(\"received SIGKILL\ \");
else if (signo == SIGSTOP)
printf(\"received SIGSTOP\ \");
//set keg to new value
N = MAX;
sop.sem_num = 0;
sop.sem_op = 1;
sop.sem_flg = 0;
if (semop(sem_id, &sop, 1))
{
perror(\"Could not increment semaphore\");
exit(5);
}
printf(\"Exiting pledge after setting keg to MAX value\");
}



