Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Project Description: The purpose is to learn how to use semaphores to protect a

ID: 3604386 • Letter: P

Question

Project Description:

The purpose is to learn how to use semaphores to protect a limited size resource. A circular buffer with 15 positions (each position stores 1 character) is to be used to communicate information between two threads (producer and consumer). The producer thread will read characters, one by one from a file and place it in the buffer and continue to do that until the “end-of-file” (EOF) marker is reached. The name of the file must be “mytest.dat” when you are submitting the program – of course you can use your own file while individually testing your program. There should be no more than 150 characters in the file. The producer must inform the consumer when it has finished placing the last character in the buffer. The producer could do this by placing a special character for example, ”*” in the shared buffer or by using a shared memory flag that the producer sets to true and the consumer reads at the appropriate time

Consumer thread will read the characters, one by one, from the shared buffer and print it to the screen. A parent process will create both producer and consumer threads and will wait until both are finished to destroy semaphores. The consumer should run slower than producer. So, place a one second sleep in the consumer thread between “reads” from the shared memory.

Sample Output:

The output your program produces will be reconstruction of the original thread contained in “mytest.dat”. It need not include the “*” character.

Use the following header for your program

#define _REENTRANT

#include <pthread.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <sys/wait.h>

#include <fcntl.h>

#include <semaphore.h>

You will require 3 semaphores;

The buffer should be treated as circular buffer

Below is a piece of “C” code that gives you some idea of how to open file and read from file

char newChar;

FILE* fp;

fp= fopen("mytest.dat", "r");

while(fscanf(fp,"%c",&newChar) != EOF)

………………………………………………..

close(fp);

To compile program use the command:

gcc name_of_program.c -lpthread -lrt

The semaphore functions:

sem_t sem1;

sem_wait(&sem1);

sem_post(&sem1);

sem_init(&sem1, …,…);

sem_destroy(&sem1);

Explanation / Answer

#include<stdio.h>

#include<stdlib.h>

#include<pthread.h>

#include<semaphore.h>

#define N 15

int s_buff[N];

int f=-1;

int r=-1;

sem_t mutex,nfreeBuffer,nloadedBuffer;

int p=0;

void *producer(void *ptrd){

int ptr=(int)ptrd;

int i,j;

if(p==0)

for(i=0;i<4;i++){

sem_wait(&nfreeBuffer);//waiting conditions

sem_wait(&mutex);

printf("Producer : %d ",ptr);//critical section

r=(r+1)%N;

if(f==-1) f=r;

s_buff[r]=i+1;

printf(" ");

for ( j=0;j<5;j++)

printf("%d ",s_buff[j]);

printf(" ");

sem_post(&mutex);//posting conditions

sem_post(&nloadedBuffer);

sleep(1);

}

}

void *consumer(void *ctrd){

int ctr=(int)ctrd;

int i,j;

if(p==1)

for(i=0;i<4;i++){

sem_wait(&nloadedBuffer);//waiting conditions

sem_wait(&mutex);

printf("Consumer : %d ",ctr);//critical section

s_buff[f]=0;

if (f==r) f=r=-1;

else f=(f+1)%N;

printf(" ");

for ( j=0;j<5;j++)

printf("%d ",s_buff[j]);

printf(" ");

sem_post(&mutex);//posting conditions

sem_post(&nfreeBuffer);

sleep(1);

}

}

int main(){

sem_init(&mutex,0,1);//3 semaphores

sem_init(&nfreeBuffer,0,N);

sem_init(&nloadedBuffer,0,0);

pthread_t prod_thrd[3];//threads

pthread_t cons_thrd[3];

int i,rc;

//f=0;

for(i=0;i<3;i++)

{

rc=pthread_create(&prod_thrd[i],NULL,producer,(void *)i);

if(rc) break;

}

for(i=0;i<3;i++)

{

rc=pthread_create(&cons_thrd[i],NULL,consumer,(void *)i);

if(rc) break;

}

for(i=0;i<3;i++)

pthread_join(prod_thrd[i],NULL);

for(i=0;i<3;i++)

pthread_join(cons_thrd[i],NULL);

}