/** * Simple program demonstrating shared memory in POSIX systems. * * @author Gagne, Galvin, Silberschatz * Operating System Concepts - Seventh Edition * Copyright John Wiley & Sons - 2005. * Modified by Prof. Krishna Sivalingam UMBC, Feb. 2006 * to add producer consumer problem, as in Fig. 3.14 and 3.15 */ #include #include #include #include #include #include #include #include #define BUFFER_SIZE 10 typedef struct { int pc_buffer[BUFFER_SIZE]; int in; int out; } my_buffer; int main() { /* the identifier for the shared memory segment */ int segment_id; /* a pointer to the shared memory segment */ my_buffer *shared_memory1, *shared_memory2; /* the size (in bytes) of the shared memory segment */ int segment_size, i; pid_t pid; segment_size = sizeof(my_buffer); /** allocate a shared memory segment */ segment_id = shmget(IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR); /** attach the shared memory segment */ shared_memory1 = (my_buffer *) shmat(segment_id, NULL, 0); if (shared_memory1 < 0) { perror("Error in Attach"); exit(-1); } printf("shared memory segment %d attached at address %p\n", segment_id, shared_memory1); /* Initialize in and out values */ shared_memory1 -> in = 0; shared_memory1 -> out = 0; pid = fork(); if (pid < 0) { /* error occurred */ fprintf (stderr, "Fork Failed\n"); exit (-1); /* Get out. */ } else if (pid == 0) { /* child process is producer */ printf ("** I am the child %d **\n", pid); srandom(10000); /* Initialize random seed. */ /** attach the shared memory segment */ shared_memory2 = (my_buffer *) shmat(segment_id, NULL, 0); if (shared_memory2 < 0) { perror("Child: Error in Attach"); exit(-1); } printf("shared memory segment %d attached at address %p\n", segment_id, shared_memory2); for (i = 0; i < 20; i++) { while ((shared_memory2->in + 1) % BUFFER_SIZE == shared_memory2->out) { /* Do Nothing */ } /* Add item to buffer */ shared_memory2->pc_buffer[shared_memory2->in] = (int) random() % 1000; fprintf(stdout," Item %d produced: %d\n", i, shared_memory2->pc_buffer[shared_memory2->in]); /* Update in pointer. */ shared_memory2->in = (shared_memory2->in + 1) % BUFFER_SIZE; } /* End for; produces 20 items */ /** now detach the shared memory segment */ if ( shmdt(shared_memory2) == -1) { fprintf(stderr, "Unable to detach\n"); } exit(0); } else { /* parent process is consumer */ printf ("I am the parent %d\n", pid); for (i = 0; i < 20; i++) { while (shared_memory1->in == shared_memory1->out) { /* Do Nothing */ } fprintf(stdout,"\t\t\t Item %d consumed: %d\n", i, shared_memory1->pc_buffer[shared_memory1->out]); /* Update out pointer. */ shared_memory1->out = (shared_memory1->out + 1) % BUFFER_SIZE; } /* End for; consumes 20 items */ /** now detach the shared memory segment */ if ( shmdt(shared_memory1) == -1) { fprintf(stderr, "Unable to detach\n"); } wait (NULL); printf ("Child Complete\n"); /** now remove the shared memory segment */ shmctl(segment_id, IPC_RMID, NULL); exit (0); } return 0; }