Ex. No. :10
|
IMPLEMENTATION
OF PRODUCER AND CONSUMER PROBLEM USING SEMAPHORE
|
Aim:
To
write C program to implement producer – consumer problem using semaphore.
Problem Description:
Create two unrelated processes producer & consumer.
Create a semaphore using semget( ) system call in process Producer. Create a
shared memory using shmget( ) system call in process Producer and attach a
dynamic character array to it using shmat( ) system call. The access to this
shared memory is treated as the critical section. In process Producer define
three semaphores mutex with intial value 0, Full with initial value 1, Empty
with initial value -1. Set this value by using system call semctl() with SETALL
option. Sem_op value to decrement (-1) and increment (+1) respectively by the
system call semop(). Wait() is used for
entry section and signal() is used in exit section. Shmctl() and Semctl() is
the system call used for removing the created shared memory and semaphore by
IPC_RMID command respectively.
System Calls Used:
#include <sys/types.h>
#include
<sys/ipc.h>
#include
<sys/sem.h>
Ø
semget – gets a semaphore set identifier
Synopsis
int semget(key_t key,
int nsems, int semflg);
Description
semget() returns the semaphore set identifier associated with the argument key. A new set of nsems semaphores is created if key has the value IPC_PRIVATE or if no existing semaphore set is associated to key and IPC_CREAT is asserted in semflg (i.e. semflg & IPC_CREAT isn’t zero).
Ø
semop – semaphore
operations
Synopsis
int semop(int semid, struct sembuf *sops, unsigned nsops);
Description
The function semop performs operations on selected members of the semaphore set indicated by semid. Each of the nsops elements in the array pointed to by sops specifies an operation to be performed on a semaphore by a struct sembuf including the following members:
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
The set of operations contained in sops is performed atomically. Each operation is performed on the sem_num-th semaphore of the semaphore set, where the first semaphore of the set is semaphore 0.
There are three types of operation, distinguished by the value of sem_op.
If sem_op is a positive integer, the operation adds this value to the semaphore value (semval). If sem_op is zero, the process must have read access permission on the semaphore set. If sem_op, is a negative integer, the value of sem_op is subtracted from semval
Ø
semctl – semaphore control operations
Synopsis
int semctl(int semid, int semnum, int cmd, ...);
Description
semctl performs the control
operation specified by cmd on the semaphore set identified by semid,
or on the semnum-th semaphore of that set. (Semaphores are numbered starting at 0.)
This function has
three or four arguments. ; where the
fourth argument arg has a type union semun
defined as follows:
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
The cmd SETALL sets semval for all semaphores of the set using arg.array and GETALL gets semval for all semaphores of the set using arg .array
Ø
shmget - allocates a shared memory segment
Synopsis
int
shmget(key_t key, size_t size, int shmflg);
Description
shmget() returns the identifier of the shared memory segment associated with the value of the argument key. A new shared memory segment, with size equal to the value of size rounded up to a multiple of PAGE_SIZE, is created if key has the value IPC_PRIVATE or key IPC_PRIVATE, no shared memory segment corresponding to key exists, and IPC_CREAT is asserted in shmflg (i.e. shmflg & IPC_CREAT isn’t zero)
Ø
shmat, shmdt - shared memory operations
Synopsis
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
Description
The function shmat( ) attaches the shared memory segment identified by shmid to the address space of the calling process.
The function shmdt() detaches the shared memory segment located at the address specified
by shmaddr from the address space of the calling
process. The segment will automatically be detached at process exit.
Ø shmctl - shared
memory control
Synopsis
int
shmctl(int shmid, int cmd, struct shmid_ds *buf);
Description
shmctl() performs the
control operation specified by cmd on the shared memory segment whose
identifier is given in shmid.
Valid values for cmd are:
- IPC_STAT is used to copy information about the shared
memoy segment from the kernel data structure associated with shmid into
the shmid_ds structure pointed to by buf.
- IPC_SET
is used to apply the changes the
user has made. The following fields can be changed: uid, gid, and (the
least significant 9 bits of) mode.
- IPC_RMID is used to mark the segment to be destroyed. The
segment will only actually be destroyed after the last process detaches
it.
Algorithm
Step
1: Start the program
Step
2: The producer must first create a new buffer area using shared memory.
Step
3: Checks to see if the buffer is full. If it is, the producer will put the
processor itself to sleep until the consumer wakes up. A wake up comes if the
consumer find buffer as empty.
Step
4: The producer put the produced item in buffer. If the producer goes to sleep
in step3.
//Program for producer consumer problem
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#define N 5
#define BUFSIZE 1
#define PERMS 0666
int *buffer;
int nextp=0,nextc=0;
int mutex,full,empty; //semaphore variables
void producer()
{
int data;
if(nextp == N)
nextp=0;
printf("\nEnter the data(producer)
:");
scanf("%d",(buffer+nextp));
nextp++;
}
void consumer()
{
int g;
if(nextc == N)
nextc=0;
g=*(buffer+nextc++);
printf("\nconsumer consumes the
data:%d",g);
}
void sem_op(int id, int value)
{
struct sembuf op;
int v;
op.sem_num=0;
op.sem_op=value;
op.sem_flg=SEM_UNDO;
if((v=semop(id,&op,1)) < 0)
printf("\n Error executing semop instruction");
}
void sem_create(int semid, int
initval)
{
int semval;
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
}s;
s.val=initval;
if((semval=semctl(semid,0,SETVAL,s))<0)
printf("\n Erroe in executing semctl");
}
void sem_wait(int id)
{
int value = -1;
sem_op(id,value);
}
void sem_signal(int id)
{
int value=1;
sem_op(id,value);
}
int main()
{
int shmid,no=1,i;
int pid,n;
if((shmid=shmget(1000,BUFSIZE,IPC_CREAT |
PERMS)) < 0)
{
printf("\n unable to create shared memory");
return;
}
if((buffer=(int*)shmat(shmid,(char*)0,0)) ==
(int*)-1)
{
printf("\n Shared memory allocation error\n");
exit(1);
}
if((mutex=semget(IPC_PRIVATE,1,PERMS |
IPC_CREAT)) == -1)
{
printf("\n can't create mutex semaphore");
exit(1);
}
if((empty=semget(IPC_PRIVATE,1,PERMS |
IPC_CREAT)) == -1)
{
printf("\n can't create empty semaphore");
exit(1);
}
if((full=semget(IPC_PRIVATE,1,PERMS |
IPC_CREAT)) == -1)
{
printf("\ncan't create full
semaphore");
exit(1);
}
sem_create(mutex,1);
sem_create(empty,N);
sem_create(full,0);
if((pid=fork()) < 0)
{
printf("\n Error in process creation");
exit(1);
}
if(pid > 0)
{
printf("\n\n parent process id:%d",pid);
for(i=0;i<5;i++)
{
sem_wait(empty);
sem_wait(mutex);
producer();
sem_signal(mutex);
sem_signal(full);
}
wait();
}
if(pid == 0)
{
printf("\n\n Child process if
%d",pid);
for(i=0;i<5;i++)
{
sem_wait(full);
sem_wait(mutex);
consumer();
sem_signal(mutex);
sem_signal(empty);
}
}
}
"poco.c" 139L, 2203C
written
[anandh@localhost ~]$ cc poco.c
[anandh@localhost ~]$ ./a.out
parent process id:14067
Enter the data(producer) :1
Enter the data(producer) :2
Child process if 0
Enter the data(producer) :3
consumer consumes the data:1
Enter the data(producer) :4
consumer consumes the data:2
Enter the data(producer) :5
consumer consumes the data:3
consumer consumes the data:4
consumer consumes the data:5
[anandh@localhost ~]$
RESULT:
Thus the C
programs to implement producer – consumer problem using semaphores were written
and executed. The outputs were verified for the given data.
No comments:
Post a Comment