User Tools

Site Tools


os_cp:shmem_semaphores:solutions

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

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
 +~~
  
os_cp/shmem_semaphores/solutions.txt · Last modified: 2024/05/08 14:44 by jkonczak