shm_consumer.c

Download
c 93 lines 2.2 KB
 1/**
 2 * Shared Memory Consumer
 3 *
 4 * Reads data from POSIX shared memory written by shm_producer.
 5 * Run shm_producer first, then this program.
 6 *
 7 * Build: make
 8 * Usage: ./shm_consumer
 9 *
10 * Note: Link with -lrt -lpthread on Linux
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <fcntl.h>
16#include <sys/mman.h>
17#include <unistd.h>
18#include <semaphore.h>
19
20#define SHM_NAME  "/study_shm"
21#define SEM_READY "/study_sem_ready"
22#define SEM_DONE  "/study_sem_done"
23
24#define NUM_ITEMS 10
25
26typedef struct {
27    int    id;
28    double value;
29    char   label[64];
30} item_t;
31
32typedef struct {
33    int    count;
34    item_t items[NUM_ITEMS];
35} shared_data_t;
36
37int main(void) {
38    /* Open semaphores */
39    sem_t *sem_ready = sem_open(SEM_READY, 0);
40    sem_t *sem_done  = sem_open(SEM_DONE,  0);
41
42    if (sem_ready == SEM_FAILED || sem_done == SEM_FAILED) {
43        fprintf(stderr, "Run shm_producer first!\n");
44        exit(EXIT_FAILURE);
45    }
46
47    /* Wait for data to be ready */
48    printf("Consumer: waiting for producer...\n");
49    sem_wait(sem_ready);
50
51    /* Open shared memory */
52    int shm_fd = shm_open(SHM_NAME, O_RDONLY, 0666);
53    if (shm_fd < 0) {
54        perror("shm_open");
55        exit(EXIT_FAILURE);
56    }
57
58    shared_data_t *shm = mmap(NULL, sizeof(shared_data_t),
59                               PROT_READ, MAP_SHARED, shm_fd, 0);
60    if (shm == MAP_FAILED) {
61        perror("mmap");
62        exit(EXIT_FAILURE);
63    }
64
65    /* Read and display data */
66    printf("Consumer: reading %d items from shared memory\n", shm->count);
67
68    double total = 0.0;
69    for (int i = 0; i < shm->count && i < NUM_ITEMS; i++) {
70        printf("  [%d] %s = %.2f\n",
71               shm->items[i].id, shm->items[i].label,
72               shm->items[i].value);
73        total += shm->items[i].value;
74    }
75    printf("  Total: %.2f, Average: %.2f\n",
76           total, total / shm->count);
77
78    /* Signal producer that we're done */
79    sem_post(sem_done);
80
81    /* Cleanup */
82    sem_close(sem_ready);
83    sem_close(sem_done);
84    sem_unlink(SEM_READY);
85    sem_unlink(SEM_DONE);
86    munmap(shm, sizeof(shared_data_t));
87    close(shm_fd);
88    shm_unlink(SHM_NAME);
89
90    printf("Consumer: done, resources cleaned up\n");
91    return 0;
92}