Tobiahao

S01_PAMIEC_DZIELONA_03

Dec 19th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.73 KB | None | 0 0
  1. /*
  2. Pokaż rozwi ą zanie problemu czytelników i pisarzy na przyk ł adzie operacji zapisu
  3. i odczytu do pami ę ci dzielonej. Do synchronizacji komunikacji u ż yj semaforów. Do
  4. wypisywania na ekran komunikatów zamiast funkcji printf() u ż yj funkcji write()
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/ipc.h>
  10. #include <sys/types.h>
  11. #include <sys/shm.h>
  12. #include <sys/sem.h>
  13. #include <unistd.h>
  14. #include <wait.h>
  15. #include <time.h>
  16. #include <string.h>
  17.  
  18. #define PROCESSES_NUMBER 16
  19. #define BUFFER_SIZE 128
  20.  
  21. struct shmdata {
  22.     char message[BUFFER_SIZE];
  23.     int readers_number;
  24. };
  25.  
  26. void error_handler(const char *msg)
  27. {
  28.     perror(msg);
  29.     exit(EXIT_FAILURE);
  30. }
  31.  
  32. void writer(int id, int mux, int shmid)
  33. {
  34.     struct sembuf up_operation = {0, 1, 0},
  35.               down_operation = {0, -1, 0};
  36.     char info[BUFFER_SIZE];
  37.     struct shmdata *shared_memory;
  38.    
  39.     if((shared_memory = (struct shmdata *)shmat(shmid, NULL, 0)) == (void *)-1)
  40.         error_handler("shmat_writer");
  41.  
  42.     if(semop(mux, &down_operation, 1) == -1)
  43.         error_handler("semop_down");
  44.    
  45.     snprintf(info, BUFFER_SIZE, "Pisarz nr: %d\n", id);
  46.     write(STDOUT_FILENO, info, strlen(info));
  47.     snprintf(shared_memory->message, SHMLBA, "Wiadomosc od pisarza nr %d\n", id);
  48.  
  49.     if(semop(mux, &up_operation, 1) == -1)
  50.         error_handler("semop_up");
  51.  
  52.     if(shmdt(shared_memory) == -1)
  53.         error_handler("shmdt");
  54. }
  55.  
  56. void reader(int id, int mux, int shmid)
  57. {
  58.     struct sembuf message_up_operation = {0, 1, 0},
  59.               message_down_operation = {0, -1, 0},
  60.               readers_up_operation = {1, 1, 0},
  61.               readers_down_operation = {1, -1, 0};
  62.     char info[BUFFER_SIZE];
  63.     struct shmdata *shared_memory;
  64.  
  65.     if((shared_memory = (struct shmdata *)shmat(shmid, NULL, 0)) == (void *)-1)
  66.         error_handler("shmat_reader");
  67.  
  68.     if(semop(mux, &readers_down_operation, 1) == -1)
  69.         error_handler("semop_down");
  70.     shared_memory->readers_number++;
  71.     if(shared_memory->readers_number == 1)
  72.         if(semop(mux, &message_down_operation, 1) == -1)
  73.             error_handler("semop_down");
  74.     if(semop(mux, &readers_up_operation, 1) == -1)
  75.         error_handler("semop_up");
  76.  
  77.     snprintf(info, BUFFER_SIZE, "Czytelnik nr: %d\n", id);
  78.     write(STDOUT_FILENO, info, strlen(info));
  79.     write(STDOUT_FILENO, shared_memory->message, sizeof(shared_memory->message));
  80.    
  81.     if(semop(mux, &readers_down_operation, 1) == -1)
  82.         error_handler("semop_down");
  83.     shared_memory->readers_number--;
  84.     if(!shared_memory->readers_number)
  85.         if(semop(mux, &message_up_operation, 1) == -1)
  86.             error_handler("semop_up");
  87.  
  88.     if(semop(mux, &readers_up_operation, 1) == -1)
  89.         error_handler("semop_up");
  90.  
  91.     if(shmdt(shared_memory) == -1)
  92.         error_handler("shmdt");
  93. }
  94.  
  95. int main(void)
  96. {
  97.     int mux, shmid;
  98.     pid_t pid;
  99.     int writer_id = 0;
  100.     int reader_id = 0;
  101.     int choice_buffer;
  102.  
  103.     //////////////////////////
  104.  
  105.     srand(time((time_t *)NULL));
  106.  
  107.     if((mux = semget(IPC_PRIVATE, 2, 0775 | IPC_CREAT | IPC_EXCL)) == -1)
  108.         error_handler("semget");
  109.  
  110.     if((shmid = shmget(IPC_PRIVATE, SHMLBA, 0775 | IPC_CREAT | IPC_EXCL)) == -1)
  111.         error_handler("shmget");
  112.  
  113.     for(int i = 0; i < 2; i++)
  114.         if(semctl(mux, i, SETVAL, 1) == -1)
  115.             error_handler("semctl_setval");
  116.  
  117.  
  118.     for(int i = 0; i < PROCESSES_NUMBER; i++){
  119.         choice_buffer = rand() % 2;
  120.         if(choice_buffer)
  121.             reader_id++;
  122.         else
  123.             writer_id++;
  124.        
  125.         pid = fork();
  126.         if(pid == -1)
  127.             error_handler("fork");
  128.         else if(pid == 0){
  129.             if(choice_buffer)
  130.                 reader(reader_id, mux, shmid);
  131.             else
  132.                 writer(writer_id, mux, shmid);
  133.             return EXIT_SUCCESS;
  134.         }
  135.     }
  136.  
  137.     for(int i = 0; i < PROCESSES_NUMBER; i++)
  138.         if(wait(NULL) == -1)
  139.             error_handler("wait");
  140.  
  141.     if(shmctl(shmid, IPC_RMID, NULL) == -1)
  142.         error_handler("shmctl");
  143.  
  144.     if(semctl(mux, 0, IPC_RMID, NULL) == -1)
  145.         error_handler("semctl");
  146.  
  147.     return EXIT_SUCCESS;
  148. }
Add Comment
Please, Sign In to add comment