The Producer-Consumer Problem in Operating System | OS Tutorials YASH PAL, June 2, 2026June 2, 2026 The Producer consumer problem describes two processes, the producer and the consumer, who share a common fixed-size buffer. This is a well known problem in Interprocess Communication/Synchronization in operating system and also known as Bounded Buffer problem.Table of Contents Producer Consumer ProblemNon-semaphore SolutionSolution Program in C ProgrammingSemaphore-based SolutionC Program of Producer Consumer Problem (using Semaphore)Producer Consumer ProblemIn this problem the producer’s job is to generate a piece of data, put it into the buffer and start again. At the same time the consumer is consuming the data (i.e. removing it from the buffer) one piece ata time. Trouble arises when the Producer wants to put a new item in the buffer, but it is already full.The solution for the producer consumer problem is for the producer to block (ie, go to sleep), to be awakened when the consumer has removed one or more items. Similarly, if the Consumer wants to remove an item from the buffer and sees that the buffer is empty, it blocks until the Producer puts something in the buffer and wakes it up. There are many software situations which match this scenario.Non-semaphore SolutionThe following “solution” contains a fatal race condition.The essence of the problem is that access to the count variable is not mutually exclusive.Solution Program in C Programming#define N 100 int count = 0; void producer(void) { int item; while(TRUE){ produce_item(&item); if(count == N) sleep(); enter_item(item); count = count + 1; if(count == 1) wakeup(consumer); } } void consumer(void) { int item; while(TRUE){ if(count == 0) sleep(); remove_item(&item); count = count - 1; if(count == N-1) wakeup(producer); consume_item(item); } }#define N 100 int count = 0; void producer(void) { int item; while(TRUE){ produce_item(&item); if(count == N) sleep(); enter_item(item); count = count + 1; if(count == 1) wakeup(consumer); } } void consumer(void) { int item; while(TRUE){ if(count == 0) sleep(); remove_item(&item); count = count - 1; if(count == N-1) wakeup(producer); consume_item(item); } }Semaphore-based Solutiontypedef int semaphore; semaphore mutex = 1; /* controls access to critical region */ semaphore empty = N; /* counts empty buffer slots */ semaphore full = 0; void producer(void) { int item; while(1){ produce_item(&item); down(&empty); /* decrement empty count */ down(&mutex); /* enter criticall region */ enter_item(&item); /* put new item in buffer */ up(&mutex); /* leave critical region */ up(&full); /* increment count of full slots */ } } void consumer(void) { int item; while(1) { down(&full); /* decrement full count */ down(&mutex); /* enter critical region */ remove_item(&item); /* take item from buffer */ up(&mutex); /* leave critical region */ up(&empty); /* increment count of empty slots */ consume_item(item); } }typedef int semaphore; semaphore mutex = 1; /* controls access to critical region */ semaphore empty = N; /* counts empty buffer slots */ semaphore full = 0; void producer(void) { int item; while(1){ produce_item(&item); down(&empty); /* decrement empty count */ down(&mutex); /* enter criticall region */ enter_item(&item); /* put new item in buffer */ up(&mutex); /* leave critical region */ up(&full); /* increment count of full slots */ } } void consumer(void) { int item; while(1) { down(&full); /* decrement full count */ down(&mutex); /* enter critical region */ remove_item(&item); /* take item from buffer */ up(&mutex); /* leave critical region */ up(&empty); /* increment count of empty slots */ consume_item(item); } }C Program of Producer Consumer Problem (using Semaphore)#include<stdio.h> #include<sys/types.h> #include<sys/sem.h> #include<stdlib.h> #include<sys/shm.h> #include<errno.h> #include<sys/ipc.h> void sem_acq(int); void sem_rel(int); int main() { int mutex, empty, full, shmid, n; pid_t ret; int in= -1, out= -1; char *buffer; char c[2]; printf("\nProducer Consumer Problem using Semaphore\n"); printf("\nEnter the size for buffer:"); scanf("%d", &n); if(mutex = semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1){ perror("\nFailed to create semaphore."); exit(0); } if(semctl(mutex,0,SETVAL,1)) == -1){ perror("\nFailed to set value for the semaphore."); exit(0); } if((empty=semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1) { perror("\nFailed to create semaphore."); exit(0); } if((semctl(empty,0,SETVAL,n)) == -1){ perror("\nFailed to set value for semaphore."); exit(0); } if((full=semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1){ perror("\nFailed to create semaphore."); exit(0); } if(semctl(full,0,SETVAL,0)) == -1){ perror("\nFailed to set value for the semaphore."); exit(0); } if((shmid = shmget(IPC_PRIVATE, n*sizeof(char), 0666|IPC_CREAT)) == -1) perror("\nFailed to allocate shared memory."); exit(0); } buffer=(char *)shmat(shmid,(const void*)0,0); ret=fork(); while(1){ if(ret == 0) //Producer { sem_acq(empty); printf("\nItem produced: "); scanf("%s",c); sem_acq(mutex); in = (in+1)%n; buffer[in] = c[0]; sem_rel(mutex); sem_rel(full); } else if(ret>0) //Consumer { sleep(5); sem_acq(full); sem_acq(mutex); out = (out+1)%n; c[0] = buffer[out]; printf("\nItem consumed: %c",c[0]); sem_rel(mutex); sem_rel(empty); } } } void sem_acq(int semid) { struct sembuf sb; sb.sem_num=0; sb.sem_op=1; sb.sem_flg=0; if((semop(semid,&sb,1))== -1){ perror("\nFailed to acquire semaphore."); exit(0); } } void sem_rel(int semid) { struct sembuf sb; sb.sem_num = 0; sb.sem_op=1; sb.sem_flg=0; if((semop(semid,&sb,1)) == -1){ perror("\nFailed to release semaphore."); exit(0); } }#include<stdio.h> #include<sys/types.h> #include<sys/sem.h> #include<stdlib.h> #include<sys/shm.h> #include<errno.h> #include<sys/ipc.h> void sem_acq(int); void sem_rel(int); int main() { int mutex, empty, full, shmid, n; pid_t ret; int in= -1, out= -1; char *buffer; char c[2]; printf("\nProducer Consumer Problem using Semaphore\n"); printf("\nEnter the size for buffer:"); scanf("%d", &n); if(mutex = semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1){ perror("\nFailed to create semaphore."); exit(0); } if(semctl(mutex,0,SETVAL,1)) == -1){ perror("\nFailed to set value for the semaphore."); exit(0); } if((empty=semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1) { perror("\nFailed to create semaphore."); exit(0); } if((semctl(empty,0,SETVAL,n)) == -1){ perror("\nFailed to set value for semaphore."); exit(0); } if((full=semget(IPC_PRIVATE,1,0666|IPC_CREAT)) == -1){ perror("\nFailed to create semaphore."); exit(0); } if(semctl(full,0,SETVAL,0)) == -1){ perror("\nFailed to set value for the semaphore."); exit(0); } if((shmid = shmget(IPC_PRIVATE, n*sizeof(char), 0666|IPC_CREAT)) == -1) perror("\nFailed to allocate shared memory."); exit(0); } buffer=(char *)shmat(shmid,(const void*)0,0); ret=fork(); while(1){ if(ret == 0) //Producer { sem_acq(empty); printf("\nItem produced: "); scanf("%s",c); sem_acq(mutex); in = (in+1)%n; buffer[in] = c[0]; sem_rel(mutex); sem_rel(full); } else if(ret>0) //Consumer { sleep(5); sem_acq(full); sem_acq(mutex); out = (out+1)%n; c[0] = buffer[out]; printf("\nItem consumed: %c",c[0]); sem_rel(mutex); sem_rel(empty); } } } void sem_acq(int semid) { struct sembuf sb; sb.sem_num=0; sb.sem_op=1; sb.sem_flg=0; if((semop(semid,&sb,1))== -1){ perror("\nFailed to acquire semaphore."); exit(0); } } void sem_rel(int semid) { struct sembuf sb; sb.sem_num = 0; sb.sem_op=1; sb.sem_flg=0; if((semop(semid,&sb,1)) == -1){ perror("\nFailed to release semaphore."); exit(0); } } engineering subjects Operating System Operating System