/****************************************************************************** * Solution for Lab Test 2 (lt2.c) * * Written by Abhijit Das * * Date: November 03, 2009 * ******************************************************************************/ #include #include #include #include #include #include #include #include #include char *BUF; /* shared buffer */ int M, X, Y; /* ID for shared memory and semaphores */ FILE *fp; /* Input file pointer for producer */ int DONE = 0; /* Termination flag (not shared) */ #define P(s) semop(s,&pop,1) #define V(s) semop(s,&vop,1) struct sembuf pop, vop; void init(); /* For Part 1 */ void produce(); /* For Part 2 */ void consume(); /* For Part 3 */ void ploop(); /* For Part 4 */ void cloop(); /* For Part 4 */ void windup(); /* For Part 5 */ /* Part 1: Initialization */ void init () { /* Create shared memory and semaphores */ M = shmget(IPC_PRIVATE, 100*sizeof(char), 0777|IPC_CREAT); X = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT); Y = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT); /* Initialize the semaphores */ semctl(X,0,SETVAL,0); semctl(Y,0,SETVAL,0); /* Initialize struct sembuf values for P() and V() */ pop.sem_num = vop.sem_num = 0; pop.sem_flg = vop.sem_flg = 0; pop.sem_op = -1; vop.sem_op = 1; /* Fork the consumer process */ if (fork()) { /* Parent the producer */ fp = (FILE *)fopen("inp.txt", "r"); /* Open file pointer for reading */ BUF = (char *)shmat(M,0,0); /* Attach to shared memory */ ploop(); /* Enter production loop */ } else { /* Child the consumer */ BUF = (char *)shmat(M,0,0); /* Attach to shared memory */ cloop(); /* Enter consumption loop */ } } /* Part 2: The production primitive */ void produce () { int i; char c; i = 0; c = '\0'; /* Read a line from the input file including the trailing new line char */ while (c != '\n') { fscanf(fp, "%c", &c); if (feof(fp)) break; /* feof() is true, after an fscanf() fails */ BUF[i++] = c; } /* Terminate BUF by the null character */ BUF[i] = '\0'; /* If a line is read from the input file, then i >= 1, since at least the trailing new-line character is read. If i = 0, then EOF is reached, so terminate. */ if (i == 0) DONE = 1; } /* Part 3: The consumption primitive */ void consume () { /* If a line (including the trailing new line) is written by the producer, the length of BUF is at least one. */ if (strlen(BUF) >= 1) printf("Consumer: %s", BUF); else DONE = 1; } /* Part 4: synchronization of producer and consumer in the loops */ /* Production loop */ void ploop () { while (1) { produce(); /* Produce a line of text */ V(Y); /* Wake up the consumer */ if (DONE) break; /* If the input file is finished, return */ P(X); /* Wait for consumer to read buffer */ } } /* Consumption loop */ void cloop () { while (1) { P(Y); /* Wait for producer to finish writing */ consume(); /* Print the buffer */ if (DONE) exit(0); /* All ines have come */ V(X); /* Wake up the producer for the next line */ } } /* Part 5: Deletion of shared resources by the producer */ void windup () { wait(NULL); /* Wait for consumer to terminate */ shmdt(BUF); /* Detach from shared memory */ shmctl(M, IPC_RMID, 0); /* Delete shared memory */ semctl(X, 0, IPC_RMID, 0); /* Delete semaphore */ semctl(Y, 0, IPC_RMID, 0); /* Delete semaphore */ } int main () { init(); windup(); /* Part 1 */ exit(0); /* Part 5 */ } /******************************** End of lt2.c ********************************/