Advertisement
Guest User

Untitled

a guest
Apr 21st, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.93 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/wait.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <sys/ipc.h>
  6. #include <sys/sem.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <errno.h>
  10.  
  11.  
  12. int main()
  13. {
  14.     int fd[2], result;
  15.     size_t rw;
  16.     char resstring[64];
  17.    
  18.     int semid;
  19.     key_t key;
  20.    
  21.     if((key = ftok("p4.c", 0)) < 0) {
  22.         printf("Can't generate key\n");
  23.         exit(-1);
  24.     }
  25.    
  26.     if((semid = semget(key, 3, 0666 | IPC_CREAT)) < 0){
  27.         printf("Can't get semid\n");
  28.         exit(-1);
  29.     }
  30.    
  31.     //Семафор 0 - признак наличия данных в пайпе, 0 - есть, 1 - нет
  32.     //Семафор 1 - признак очереди родителя, 0 - да, 1 - нет
  33.     //Семафор 2 - признак очереди потомка, 0 - да, 1 - нет
  34.    
  35.     struct sembuf mybuf;
  36.     mybuf.sem_op = 1;
  37.     mybuf.sem_flg = 0;
  38.     mybuf.sem_num = 0;
  39.     //Устанавливаем отсутствие данных в пайпе
  40.     semop(semid, &mybuf, 1);
  41.     mybuf.sem_num = 2;
  42.     //Увеличиваем семафор 2 на 1, чтобы первым действовал родитель
  43.     semop(semid, &mybuf, 1);
  44.     mybuf.sem_op = 0;
  45.    
  46.     if(pipe(fd) < 0) {
  47.         printf("Can't create pipe\n");
  48.         exit(-1);
  49.     }
  50.    
  51.     result = fork();
  52.    
  53.     if(result <0) {
  54.         printf("Can't fork child\n");
  55.         exit(-1);
  56.     } else if (result > 0) {
  57.         //parent
  58.         char *msg[] = {
  59.             "Parent message 1",
  60.             "Parent message 2",
  61.             "Parent message 3",
  62.             "Parent message 4",
  63.             "Parent message 5"
  64.         };
  65.        
  66.         int s = 0, r = 0, hd = 0;
  67.        
  68.        
  69.         while(1) {
  70.             //Пытаемся занять канал
  71.             mybuf.sem_num = 1;
  72.             mybuf.sem_op = 0;
  73.             if(semop(semid, &mybuf, 1) < 0) {
  74.                 printf("Parent: failed to wait sem 1\n");
  75.                 perror("Parent");
  76.                 exit(-1);
  77.             }
  78.             //Заняли
  79.             //Проверяем, есть ли данные в канале
  80.             mybuf.sem_op = 0;
  81.             mybuf.sem_flg = IPC_NOWAIT;
  82.             mybuf.sem_num = 0;
  83.             if(!(semop(semid, &mybuf, 1) < 0)) {
  84.                 //Есть данные в канале
  85.                 //Получаем и пишем
  86.                 printf("Parent: Got message\n");
  87.                 read(fd[0], resstring, 64);
  88.                 printf("MSG_PARENT: %s\n", resstring);
  89.                 r++;
  90.                 hd = 1;
  91.             } else {
  92.                 hd = 0;
  93.             }
  94.             //Посылаем данные, если еще не выслали все
  95.             if(s < 5) {
  96.                 write(fd[1], msg[s], strlen(msg[s])+1);
  97.                 s++;
  98.                 printf("Parent: Sent message\n");
  99.                 if(!hd) {
  100.                     //Если в канале не было данных
  101.                     mybuf.sem_op = -1;
  102.                     mybuf.sem_flg = 0;
  103.                     mybuf.sem_num = 0;
  104.                     semop(semid, &mybuf, 1);
  105.                     printf("Parent: No data in pipe, set sem 0 to 0\n");
  106.                 }
  107.             } else if(hd) {
  108.                 //Прочитали, но не написали, а данные в канале были
  109.                 mybuf.sem_op = 1;
  110.                 mybuf.sem_flg = 0;
  111.                 mybuf.sem_num = 0;
  112.                 semop(semid, &mybuf, 1);
  113.                 printf("Parent: Has data, but nothing to sent, set sem 0 to 1\n");
  114.             }
  115.            
  116.             //Освобождаем канал
  117.             mybuf.sem_op = 1;
  118.             mybuf.sem_num = 1;
  119.             mybuf.sem_flg = 0;
  120.             if(semop(semid, &mybuf, 1) < 0) {
  121.                 printf("Parent: failed to set sem 1 to 1\n");
  122.                 perror("Parent");
  123.                 exit(-1);
  124.             }
  125.             //Передаем ход потомку
  126.             mybuf.sem_num = 2;
  127.             mybuf.sem_op = -1;
  128.             if(semop(semid, &mybuf, 1) < 0) {
  129.                 printf("Parent: failed to set sem 2 to 0\n");
  130.                 perror("Parent");
  131.                 exit(-1);
  132.             }
  133.  
  134.             if(r == 5 && s == 5)
  135.                 break;
  136.         }
  137.         printf("Parent exit\n");
  138.         //size = write(fd[1], "Hello, world!", 14);
  139.         //printf("Parent exit, writed %d\n", size);
  140.     } else {
  141.         //child
  142.         char *msg[] = {
  143.             "Child message 1",
  144.             "Child message 2",
  145.             "Child message 3",
  146.             "Child message 4",
  147.             "Child message 5"
  148.         };
  149.         //size = read(fd[0], resstring, 14);
  150.         int s = 0, r = 0, hd = 0;
  151.        
  152.         while(1) {
  153.             //Пытаемся занять канал (потомок)
  154.             mybuf.sem_num = 2;
  155.             mybuf.sem_op = 0;
  156.             if(semop(semid, &mybuf, 1) < 0) {
  157.                 printf("Child: failed to wait sem 2\n");
  158.                 perror("Child");
  159.                 exit(-1);
  160.             }
  161.             //Заняли
  162.             //Проверяем, есть ли данные в канале
  163.             mybuf.sem_op = 0;
  164.             mybuf.sem_flg = IPC_NOWAIT;
  165.             mybuf.sem_num = 0;
  166.             if(!(semop(semid, &mybuf, 1) < 0)) {
  167.                 //Есть данные в канале
  168.                 //Получаем и пишем
  169.                 printf("Child: Got message\n");
  170.                 read(fd[0], resstring, 64);
  171.                 printf("MSG_CHILD: %s\n", resstring);
  172.                 r++;
  173.                 hd = 1;
  174.             } else {
  175.                 hd = 0;
  176.             }
  177.             //Посылаем данные, если еще не выслали все
  178.             if(s < 5) {
  179.                 write(fd[1], msg[s], strlen(msg[s])+1);
  180.                 s++;
  181.                 printf("Child: Sent message\n");
  182.                 if(!hd) {
  183.                     //Если в канале не было данных
  184.                     mybuf.sem_op = -1;
  185.                     mybuf.sem_flg = 0;
  186.                     mybuf.sem_num = 0;
  187.                     semop(semid, &mybuf, 1);
  188.                     printf("Child: No data in pipe, set sem 0 to 0\n");
  189.                 }
  190.             } else if(hd) {
  191.                 //Прочитали, но не написали, а данные в канале были
  192.                 mybuf.sem_op = 1;
  193.                 mybuf.sem_flg = 0;
  194.                 mybuf.sem_num = 0;
  195.                 semop(semid, &mybuf, 1);
  196.                 printf("Child: Has data, but nothing to sent, set sem 0 to 1\n");
  197.             }
  198.            
  199.             //Освобождаем канал
  200.             mybuf.sem_op = 1;
  201.             mybuf.sem_num = 2;
  202.             mybuf.sem_flg = 0;
  203.             if(semop(semid, &mybuf, 1) < 0) {
  204.                 printf("Child: failed to set sem 2 to 1\n");
  205.                 perror("Child");
  206.                 exit(-1);
  207.             }
  208.             //Передаем ход родителю
  209.             mybuf.sem_num = 1;
  210.             mybuf.sem_op = -1;
  211.             if(semop(semid, &mybuf, 1) < 0) {
  212.                 printf("Child: failed to set sem 1 to 0\n");
  213.                 perror("Child");
  214.                 exit(-1);
  215.             }
  216.            
  217.            
  218.             if(r == 5 && s == 5)
  219.                 break;
  220.         }
  221.         printf("Child exit\n");
  222.         exit(0);
  223.         //printf("%s\n",resstring);
  224.        
  225.     }
  226.     waitpid(result, &rw, 0);
  227.     printf("Sem's removed\n");
  228.     semctl(semid, 0, IPC_RMID, 0);
  229.     return 0;
  230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement