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

Objective The objective of this assignment is to use semaphores to protect the c

ID: 3595622 • Letter: O

Question

Objective The objective of this assignment is to use semaphores to protect the critical section between two competing threads. Assignment: Using Threads and Mutex/Counting Semaphores The idea is to write a C program that creates two threads. The first thread is the consumer thread that consumes the data written to a shared memory buffer. The second thread is the producer thread that "produces" the data for the shared memory buffer. In order to prevent a race condition (e.g. the consumer reading before the producer writing) use a mutex semaphore and counting semaphores to coordinate when each thread can safely write or read to/from a common shared memory region. Prodcon Program Implementation r/consumer program (prodcon.c) that takes three arguments from the command line (no prompting the user from within the program). . To start the prodcon program prodcon ntmes> where

Explanation / Answer

Code:

#include "prodcon.h"

int main(int argc, char * argv[])

{

pid_t pid;   

FILE *input_file, *output_file;

char file_buffer[MAX_BUF_SIZE];

int smem_id;

key_t smem_key = KEY_CODE;

void *temp_ptr = (void *)0;

struct shared_mem_struct *shared_mem;

if(argc == 1)

{

printf("Error: Please provide input file name ");

exit(EXIT_FAILURE);

}

if(argc != 2)

{

printf("Error: Incorrect number of arguments passed ");

exit(EXIT_FAILURE);

}

initializeWait();

if ((pid = fork()) < 0)

{

perror("fork");

exit(EXIT_FAILURE);

}

/* Parent Process */

else if (pid != 0)

{

if((input_file = fopen(argv[1],"r")) == NULL)

{

perror("fopen");

exit(EXIT_FAILURE);

}

/* Creating shared memory segment */

if((smem_id = shmget(smem_key, sizeof(struct shared_mem_struct), IPC_CREAT | 0666))<0)

{  

perror("shmget");

exit(EXIT_FAILURE);

}

/* Attaching the shared memory to data space */

if((temp_ptr = shmat(smem_id, (void *)0, 0)) == (void *)-1)

{  

perror("shmat");

exit(EXIT_FAILURE);

}

shared_mem = (struct shared_mem_struct *) temp_ptr;

shared_mem->count = 0; // Set the counter to 0

while(fgets(file_buffer, (MAX_BUF_SIZE-1), input_file) != NULL)

{

/* Wait for child to read everything from shared memory */

while(shared_mem->count != 0)

{

waitChild();

}

strcpy(shared_mem->buffer,file_buffer);

shared_mem->count = strlen(shared_mem->buffer);

}

initializeWait();

while(shared_mem->count != 0)

{

waitChild();

}

shared_mem->count = -1;

signalChild(pid);

waitpid(pid, NULL, 0);

fclose(input_file);

if(shmdt(shared_mem) == -1)

{

perror("shmdt");

exit(EXIT_FAILURE);

}

if(shmctl(smem_id, IPC_RMID, 0) == -1)

{

perror("shmctl");

exit(EXIT_FAILURE);

}

printf(" Success: The input file provided by you has been successfully copied via shared memory to output file named "ouput.txt" in the current working directory. ");

}

else

{

if((output_file = fopen("output.txt","w")) == NULL)

{

perror("fopen");

exit(EXIT_FAILURE);

}

if((smem_id = shmget(smem_key, sizeof(struct shared_mem_struct), IPC_CREAT | 0666))<0)

{

perror("shmget");

exit(EXIT_FAILURE);

}

/* Attaching the shared memory to data space */

if((temp_ptr = shmat(smem_id, (void *)0, 0)) == (void *)-1)

{

perror("shmat");

exit(EXIT_FAILURE);

}

shared_mem = (struct shared_mem_struct *) temp_ptr;

by parent process */

while(shared_mem->count != -1)

{

while(shared_mem->count == 0)

{

waitParent();

}

if(shared_mem->count != -1)

{

/* Copy the text written on shared memory buffer to ouput file */

fputs(shared_mem->buffer, output_file);

shared_mem->count = 0;   

signalParent(getppid());   

}

}

fclose(output_file);

if(shmdt(shared_mem) == -1)

{

perror("shmdt");

exit(EXIT_FAILURE)

kill(getpid(), SIGTERM);   

}

exit(EXIT_SUCCESS);

}