/** * Simple program demonstrating shared memory in POSIX systems. * This is the consumer process * * @author Agustín J. González * One line at the time is read from stdin by producer and written in the shared memory. * Then the consumer reads each line and displays it. * This a variant of a very similar program by Gagne, Galvin, Silberschatz * Operating System Concepts - Ninth Edition * Copyright John Wiley & Sons - 2013 * * modifications by dheller@cse.psu.edu, 31 Jan. 2014 * modifications by Agustín J. González, 14 Oct. 2019 * gcc consumer.c -lpthread -lrt * modifications by Agustín J. González, 27 Sept. 2022 * display function was removed to focus the code on sharing mechanism */ #include #include #include #include #include #include #include #include #include #include void display(char *prog, char *bytes, int n); int main(void) { const char *name = "/shm-example"; /* file name */ const int SIZE = 4096; /* file size */ const char *nameEmpty = "/EMPTY"; const char *nameFull = "/FULL"; int shm_fd; // file descriptor, used with shm_open() char *shm_base; // base address, used with mmap() sem_t * empty_sem, *full_sem; /* open the shared memory segment as if it were a file */ shm_fd = shm_open(name, O_RDONLY, 0666); if (shm_fd == -1) { printf("cons: Shared memory failed: %s\n", strerror(errno)); exit(1); } /* map the shared memory segment to the address space of the process */ shm_base = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); if (shm_base == MAP_FAILED) { printf("cons: Map failed: %s\n", strerror(errno)); exit(1); /* Cleanup of shm_open was not done */ } /** * Open the two named semaphores */ /* create and initialize the semaphore */ if ( (empty_sem = sem_open(nameEmpty, 0)) == SEM_FAILED) printf("Error opening %s: %s\n",nameEmpty, strerror(errno)); if ( (full_sem = sem_open(nameFull, 0)) == SEM_FAILED) printf("Error opening %s: %s\n",nameFull, strerror(errno)); do { if (sem_wait(full_sem)!=0) printf("Error waiting %s\n",strerror(errno)); else { /* read from the mapped shared memory segment */ printf("%s", shm_base); if (sem_post(empty_sem)!=0) printf("Error posting %s\n",strerror(errno)); } } while (strlen(shm_base) > 0); sem_close(empty_sem); sem_unlink(nameEmpty); sem_close(full_sem); sem_unlink(nameFull); /* remove the mapped shared memory segment from the address space of the process */ if (munmap(shm_base, SIZE) == -1) { printf("cons: Unmap failed: %s\n", strerror(errno)); exit(1); } /* close the shared memory segment as if it was a file */ if (close(shm_fd) == -1) { printf("cons: Close failed: %s\n", strerror(errno)); exit(1); } /* remove the shared memory segment from the file system */ if (shm_unlink(name) == -1) { printf("cons: Error removing %s: %s\n", name, strerror(errno)); exit(1); } return 0; }