/********************************************************************** * * ProcReaders.c * * Module for the Readers / Writers problem which favors readers using * processes. * * Author: Nick DiZazzo, April 2007 * CS305 Programming Assignment 3 - Readers / Writers Problem * *********************************************************************/ #include #include #include #include #include #include "Constants.h" #include "Processes.h" #include "ProcReaders.h" #include "ReadWrite.h" #include "Sem.h" /* Global Variables - absolutely nessecary, shared between processes. */ int readCount; /********************************************************************** * pr_readersWriters() * * This function creates the specified number of reader processes, and * the specified number of writers processes, then has each new * process execute its associated reader/writer algorithm. This version * favors readers. * * It is nearly impossible to have a perfect outcome every time * demonstrating the solution clearly, but there are some techniques that * improve the demonstration. Interleaving the process creation helps this * slightly, but there are still too many factors to create a perfect * demonstration. * * By creating two child processes which in turn create readers and * writers, we achieve pseudo-process interleaving, naturally * generated by the OS process scheduler. This sharing of CPU time between * the two launcher children is what achieves this effect. * * Parameters: readers - The number of reader processes to create. * writers - The number of writer processes to create. * * Output: None. * Pre-Conditions: None. * Post-Conditions: None. * Other: This function modifies globals: * readCount * C_W_XSEM * C_W_RSEM *********************************************************************/ void pr_readersWriters(int readers, int writers) { pid_t pPID; // parent manages semiphores pid_t c1PID; // c1 launches readers pid_t c2PID; // c2 launches writers key_t semkey; int semid; readCount = 0; // Create semaphores semkey = ftok(C_KEYFILE, C_KEYCHAR); semid = semget(semkey, C_R_NUMSEMS, 0666 | IPC_CREAT); // Initialize semaphores sem_init(semid, C_R_XSEM); // Initialize XSEM sem_init(semid, C_R_WSEM); // Initialize WSEM // Create child processes pPID = getpid(); // Store parent PID c1PID = fork(); // Create child if (pPID == getpid()) { c2PID = fork(); if (c2PID == (pid_t)C_CHILD) c1PID = C_STOPFLG; // C2 -> Mark C1 PID } else if (c1PID == (pid_t)C_CHILD) { c2PID = C_STOPFLG; // C1 -> Mark C2 PID } else { printf("%s\n", C_EM_FORKERR); exit(1); } // C1 Spawns readers, C2 Spawns writers if (c1PID == (pid_t)C_CHILD) { if (readers > 0) { createProcesses(readers-1); // Create # of readers rreader(semid); // start read routene } exit(0); // Children do no more } else if (c2PID == (pid_t)C_CHILD)