Teaching:
FeedbackThis is an old revision of the document!
#include <fcntl.h> #include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <unistd.h> #define MAX_ELEMENTS 4 typedef char item_t[256]; struct ring_buffer { item_t data[MAX_ELEMENTS]; size_t first; size_t last; }; struct ring_buffer *buffer; sem_t *storedItemsCount; sem_t *emptyItemsCount; sem_t *canModify; void put(struct ring_buffer *buffer, const item_t *item) { sem_wait(emptyItemsCount); sem_wait(canModify); memcpy(&buffer->data[buffer->last], item, sizeof(*item)); buffer->last = (buffer->last + 1) % MAX_ELEMENTS; sem_post(canModify); sem_post(storedItemsCount); } void get(struct ring_buffer *buffer, item_t *item) { sem_wait(storedItemsCount); sem_wait(canModify); memcpy(item, &buffer->data[buffer->first], sizeof(*item)); buffer->first = (buffer->first + 1) % MAX_ELEMENTS; sem_post(canModify); sem_post(emptyItemsCount); } int main() { int fd = shm_open("/myRingBuffer", O_RDWR | O_CREAT, 0666); if (fd == -1) { perror("shm_open"); exit(1); } ftruncate(fd, sizeof(struct ring_buffer)); buffer = mmap(NULL, sizeof(struct ring_buffer), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); storedItemsCount = sem_open("myRingBuffer.storedItems", O_RDWR | O_CREAT, 0666, 0); emptyItemsCount = sem_open("myRingBuffer.emptyItems", O_RDWR | O_CREAT, 0666, 4); canModify = sem_open("myRingBuffer.canModify", O_RDWR | O_CREAT, 0666, 1); printf("g gets data from buffer\n" "ptext... puts 'text...' to buffer\n"); while (1) { printf("> "); fflush(stdout); char cmd[2], c; item_t item = {0}; scanf("%1[^\n]%255[^\n]", cmd, item); do { // this reads all remaining characters in this line including '\n' c = getchar(); if (c == -1) return 0; } while (c != '\n'); switch (cmd[0]) { case 'p': put(buffer, &item); break; case 'g': get(buffer, &item); printf("%s\n", item); break; } } return 0; }