1/**
2 * Shared Memory Producer
3 *
4 * Writes data to POSIX shared memory with semaphore synchronization.
5 * Run this before shm_consumer.
6 *
7 * Build: make
8 * Usage: ./shm_producer
9 *
10 * Note: Link with -lrt -lpthread on Linux
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <fcntl.h>
17#include <sys/mman.h>
18#include <unistd.h>
19#include <semaphore.h>
20#include <time.h>
21
22#define SHM_NAME "/study_shm"
23#define SEM_READY "/study_sem_ready"
24#define SEM_DONE "/study_sem_done"
25
26#define NUM_ITEMS 10
27
28typedef struct {
29 int id;
30 double value;
31 char label[64];
32} item_t;
33
34typedef struct {
35 int count;
36 item_t items[NUM_ITEMS];
37} shared_data_t;
38
39int main(void) {
40 srand(time(NULL));
41
42 /* Create shared memory */
43 int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
44 if (shm_fd < 0) {
45 perror("shm_open");
46 exit(EXIT_FAILURE);
47 }
48 ftruncate(shm_fd, sizeof(shared_data_t));
49
50 shared_data_t *shm = mmap(NULL, sizeof(shared_data_t),
51 PROT_READ | PROT_WRITE,
52 MAP_SHARED, shm_fd, 0);
53 if (shm == MAP_FAILED) {
54 perror("mmap");
55 exit(EXIT_FAILURE);
56 }
57
58 /* Create semaphores */
59 sem_t *sem_ready = sem_open(SEM_READY, O_CREAT, 0666, 0);
60 sem_t *sem_done = sem_open(SEM_DONE, O_CREAT, 0666, 0);
61
62 /* Produce data */
63 shm->count = NUM_ITEMS;
64 for (int i = 0; i < NUM_ITEMS; i++) {
65 shm->items[i].id = i + 1;
66 shm->items[i].value = (double)(rand() % 10000) / 100.0;
67 snprintf(shm->items[i].label, sizeof(shm->items[i].label),
68 "item_%03d", i + 1);
69 }
70
71 printf("Producer: wrote %d items to shared memory\n", NUM_ITEMS);
72 for (int i = 0; i < NUM_ITEMS; i++) {
73 printf(" [%d] %s = %.2f\n",
74 shm->items[i].id, shm->items[i].label,
75 shm->items[i].value);
76 }
77
78 /* Signal consumer that data is ready */
79 sem_post(sem_ready);
80 printf("Producer: signaled consumer, waiting for acknowledgment...\n");
81
82 /* Wait for consumer to finish */
83 sem_wait(sem_done);
84 printf("Producer: consumer acknowledged. Cleaning up.\n");
85
86 /* Cleanup */
87 sem_close(sem_ready);
88 sem_close(sem_done);
89 munmap(shm, sizeof(shared_data_t));
90 close(shm_fd);
91
92 return 0;
93}