This shows you the differences between two versions of the page.
— |
os_cp:shmem_semaphores:solutions [2024/05/08 14:44] (current) jkonczak utworzono |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | <html><div style="line-height:1em"></html> | ||
+ | |||
+ | |||
+ | ~~Exercise.#3~~ | ||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <semaphore.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | sem_t *mySemaphore = sem_open("/mySemaphore", O_CREAT | O_EXCL, 0666, 0); | ||
+ | if (mySemaphore == SEM_FAILED) { | ||
+ | perror("Creating the semaphore failed"); | ||
+ | return 1; | ||
+ | } | ||
+ | sem_wait(mySemaphore); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <semaphore.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | sem_t *mySemaphore = sem_open("/mySemaphore", 0, 0666, 0); | ||
+ | if (mySemaphore == SEM_FAILED) { | ||
+ | perror("Opening the semaphore failed"); | ||
+ | return 1; | ||
+ | } | ||
+ | sem_post(mySemaphore); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | <code c> | ||
+ | #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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | Line: | ||
+ | <code c> if (createSucceeded) sleep(10);</code> | ||
+ | added anywhere after line 13 and before line 22 delays the first process from | ||
+ | initializing the semaphore for 10 seconds. If another process attempts to wait | ||
+ | on uninitialized semaphore, it is likely to get stuck forever. | ||
+ | |||
+ | |||
+ | ~~META: | ||
+ | language = en | ||
+ | ~~ | ||