Advertisement
_takumi

prog

Apr 23rd, 2023
751
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.53 KB | None | 0 0
  1. // sys v
  2. #include "message.h"
  3.  
  4. static volatile int running = 1;
  5. void inthandler(int n) {
  6.     running = 0;
  7. }
  8.  
  9. int main(int argc, char *argv[]) {
  10.     if (argc != 3) {
  11.         puts("Введите, пожалуйста, два аргумента - количество групп и количество "
  12.              "участков, на которые разделен остров.");
  13.         exit(1);
  14.     }
  15.     int groups, areas;
  16.     if (sscanf(argv[1], "%d", &groups) != 1) {
  17.         puts("Пожалуйста, введите корректное количество групп.");
  18.         exit(1);
  19.     }
  20.     if (sscanf(argv[2], "%d", &areas) != 1) {
  21.         puts("Пожалуйста, введите корректное количество участков.");
  22.         exit(1);
  23.     }
  24.  
  25.     signal(SIGINT, inthandler);
  26.  
  27.     srand(time(0));
  28.     int ans = rand() % areas + 1;
  29.  
  30.     int shmid;             // дескриптор объекта памяти
  31.     message_t *msg_p;      // адрес сообщения в разделяемой памяти
  32.     if ( (shmid = shmget(SHM_ID, sizeof(message_t), O_CREAT|PERMS)) == -1 ) {
  33.         perror("shmget");
  34.         puts("server: object is already open");
  35.         exit(1);
  36.     }
  37.     if ((msg_p = (message_t *)shmat(shmid, 0, 0)) == NULL) {
  38.         perror("shmat");
  39.         exit(1);
  40.     }
  41.    
  42.  
  43.     int semid;
  44.     struct sembuf silverunlock = {0, 1, 0};
  45.     struct sembuf silverlock = {0, -1, 0};
  46.  
  47.     struct sembuf grouplock = {1, -1, 0};
  48.     struct sembuf groupunlock = {1, 1, 0};
  49.  
  50.     struct sembuf resplock = {2, -1, 0};
  51.     struct sembuf respunlock = {2, 1, 0};
  52.  
  53.     struct sembuf understoodlock = {3, -1, 0};
  54.     struct sembuf understoodunlock = {3, 1, 0};
  55.     // mybuf.sem_num = 0;
  56.     // mybuf.sem_op  = 1; - add 1
  57.     // mybuf.sem_flg = 0;
  58.     // 0 - silverisfree
  59.     // 1 - group
  60.     // 2 - response
  61.     // 3 - understood
  62.     if((semid = semget(key, 4, 0666 | IPC_CREAT)) < 0) {
  63.       printf("Can\'t create semaphore set\n");
  64.       exit(-1);
  65.     }
  66.  
  67.     // create a a number of processes equal to 'groups'
  68.     int groupnum = 0;
  69.     int parentid = getpid();
  70.     int pids[groups];
  71.     for (int i = 0; i < groups; ++i) {
  72.         pids[i] = fork();
  73.         if (pids[i] == 0) {
  74.             groupnum = i + 1;
  75.             break;
  76.         }
  77.     }
  78.  
  79.     if (parentid == getpid()) { // main process - silver
  80.         int nextarea = 1;
  81.         int found = 0;
  82.         int groupsleft = groups;
  83.         while (running && (groupsleft > 0)) {
  84.             // sem_post(&msg_p->silverisfree);
  85.             semop(semid, &silverunlock, 1);
  86.             // sem_wait(&msg_p->groupsem);
  87.             semop(semid, &grouplock, 1);
  88.             if (msg_p->type == MSG_ASSIGN_AREA) { // first trip of a group
  89.                 msg_p->area = nextarea++;
  90.                 printf("Сильвер отправляет группу %d за кладом на участок номер %d.\n",
  91.                         msg_p->group, nextarea - 1);
  92.                 // sem_post(&msg_p->response);
  93.                 semop(semid, &respunlock, 1);
  94.                 // sem_wait(&msg_p->understood);
  95.                 semop(semid, &understoodlock, 1);
  96.             } else if (msg_p->type == MSG_REPORT) { // group has a report
  97.                 if (msg_p->data == 1) { // treasure found by current group
  98.                     printf("Йо-хо, Сильвер доволен! Группа %d нашла клад на участке %d!\n", msg_p->group, msg_p->area);
  99.                     found = 1;
  100.                     msg_p->type = MSG_TYPE_FINISH;
  101.                     --groupsleft;
  102.                     // sem_post(&msg_p->response);
  103.                     semop(semid, &respunlock, 1);
  104.                     // sem_wait(&msg_p->understood);
  105.                     semop(semid, &understoodlock, 1);
  106.                 } else { // treasure not found by current group
  107.                     if (found == 1 || nextarea > areas) { // if treasure was found before or no unsearched areas
  108.                         msg_p->type = MSG_TYPE_FINISH;
  109.                         msg_p->data = found;
  110.                         --groupsleft;
  111.                         // sem_post(&msg_p->response);
  112.                         semop(semid, &respunlock, 1);
  113.                         // sem_wait(&msg_p->understood);
  114.                         semop(semid, &understoodlock, 1);
  115.                     } else if (nextarea <= areas) {
  116.                         msg_p->type = MSG_TYPE_CONT;
  117.                         msg_p->area = nextarea++;
  118.                         // sem_post(&msg_p->response);
  119.                         semop(semid, &respunlock, 1);
  120.                         // sem_wait(&msg_p->understood);
  121.                         semop(semid, &understoodlock, 1);
  122.                     }
  123.                 }
  124.             }
  125.         }
  126.         semctl(semid, 0, IPC_RMID, 0);
  127.         shmdt(msg_p);
  128.         if (shmctl(shmid, IPC_RMID, (struct shmid_ds *)0) == -1) {
  129.             perror("shmctl");
  130.         }
  131.         puts("Пираты собрались и уплывают с острова.\n");
  132.     } else { // child processes - groups
  133.         // sem_wait(&msg_p->silverisfree);
  134.         semop(semid, &silverlock, 1);
  135.         msg_p->type = MSG_ASSIGN_AREA;
  136.         msg_p->group = groupnum;
  137.         // sem_post(&msg_p->groupsem);
  138.         semop(semid, &groupunlock, 1);
  139.         // sem_wait(&msg_p->response);
  140.         semop(semid, &resplock, 1);
  141.         int area = msg_p->area;
  142.         printf("Группа %d отправилась искать клад на участке %d.\n", groupnum, area);
  143.         // sem_post(&msg_p->understood);
  144.         semop(semid, &understoodunlock, 1);
  145.         while (running) {
  146.             int searchtime = rand() % 3 + 1;
  147.             int found;
  148.             printf("Группа %d ищет клад на участке %d...\n", groupnum, area);
  149.             sleep(searchtime);
  150.             if (area == ans) {
  151.                 printf("Группа %d нашла клад на участке %d!\n", groupnum, area);
  152.                 found = 1;
  153.             } else {
  154.                 printf("Группа %d не нашла клад на участке %d!\n", groupnum, area);
  155.                 found = 0;
  156.             }
  157.             // sem_wait(&msg_p->silverisfree);
  158.             semop(semid, &silverlock, 1);
  159.             msg_p->type = MSG_REPORT;
  160.             msg_p->group = groupnum;
  161.             msg_p->area = area;
  162.             msg_p->data = found;
  163.             // sem_post(&msg_p->groupsem);
  164.             semop(semid, &groupunlock, 1);
  165.             // sem_wait(&msg_p->response);
  166.             semop(semid, &resplock, 1);
  167.             if (msg_p->type == MSG_TYPE_FINISH) {
  168.                 if (msg_p->data == 1) {
  169.                     printf("Группа %d остается, так как сокровище найдено.\n", groupnum);
  170.                     found = 1;
  171.                 } else {
  172.                     printf("Группа %d остается, так как не осталось необысканных участков.\n", groupnum);
  173.                     found = 1;
  174.                 }
  175.             } else if (msg_p->type == MSG_TYPE_CONT) {
  176.                 area = msg_p->area;
  177.                 printf("Группа %d отправляется искать клад на участке %d.\n", groupnum, area);
  178.             }
  179.             // sem_post(&msg_p->understood);
  180.             semop(semid, &understoodunlock, 1);
  181.             if (found == 1) {
  182.                 break;
  183.             }
  184.         }
  185.         shmdt(msg_p);
  186.         exit(0);
  187.     }
  188.     return 0;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement