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 | ||
| + | ~~ | ||