Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // sys v
- #include "message.h"
- static volatile int running = 1;
- void inthandler(int n) {
- running = 0;
- }
- int main(int argc, char *argv[]) {
- if (argc != 3) {
- puts("Введите, пожалуйста, два аргумента - количество групп и количество "
- "участков, на которые разделен остров.");
- exit(1);
- }
- int groups, areas;
- if (sscanf(argv[1], "%d", &groups) != 1) {
- puts("Пожалуйста, введите корректное количество групп.");
- exit(1);
- }
- if (sscanf(argv[2], "%d", &areas) != 1) {
- puts("Пожалуйста, введите корректное количество участков.");
- exit(1);
- }
- signal(SIGINT, inthandler);
- srand(time(0));
- int ans = rand() % areas + 1;
- int shmid; // дескриптор объекта памяти
- message_t *msg_p; // адрес сообщения в разделяемой памяти
- if ( (shmid = shmget(SHM_ID, sizeof(message_t), O_CREAT|PERMS)) == -1 ) {
- perror("shmget");
- puts("server: object is already open");
- exit(1);
- }
- if ((msg_p = (message_t *)shmat(shmid, 0, 0)) == NULL) {
- perror("shmat");
- exit(1);
- }
- int semid;
- struct sembuf silverunlock = {0, 1, 0};
- struct sembuf silverlock = {0, -1, 0};
- struct sembuf grouplock = {1, -1, 0};
- struct sembuf groupunlock = {1, 1, 0};
- struct sembuf resplock = {2, -1, 0};
- struct sembuf respunlock = {2, 1, 0};
- struct sembuf understoodlock = {3, -1, 0};
- struct sembuf understoodunlock = {3, 1, 0};
- // mybuf.sem_num = 0;
- // mybuf.sem_op = 1; - add 1
- // mybuf.sem_flg = 0;
- // 0 - silverisfree
- // 1 - group
- // 2 - response
- // 3 - understood
- if((semid = semget(key, 4, 0666 | IPC_CREAT)) < 0) {
- printf("Can\'t create semaphore set\n");
- exit(-1);
- }
- // create a a number of processes equal to 'groups'
- int groupnum = 0;
- int parentid = getpid();
- int pids[groups];
- for (int i = 0; i < groups; ++i) {
- pids[i] = fork();
- if (pids[i] == 0) {
- groupnum = i + 1;
- break;
- }
- }
- if (parentid == getpid()) { // main process - silver
- int nextarea = 1;
- int found = 0;
- int groupsleft = groups;
- while (running && (groupsleft > 0)) {
- // sem_post(&msg_p->silverisfree);
- semop(semid, &silverunlock, 1);
- // sem_wait(&msg_p->groupsem);
- semop(semid, &grouplock, 1);
- if (msg_p->type == MSG_ASSIGN_AREA) { // first trip of a group
- msg_p->area = nextarea++;
- printf("Сильвер отправляет группу %d за кладом на участок номер %d.\n",
- msg_p->group, nextarea - 1);
- // sem_post(&msg_p->response);
- semop(semid, &respunlock, 1);
- // sem_wait(&msg_p->understood);
- semop(semid, &understoodlock, 1);
- } else if (msg_p->type == MSG_REPORT) { // group has a report
- if (msg_p->data == 1) { // treasure found by current group
- printf("Йо-хо, Сильвер доволен! Группа %d нашла клад на участке %d!\n", msg_p->group, msg_p->area);
- found = 1;
- msg_p->type = MSG_TYPE_FINISH;
- --groupsleft;
- // sem_post(&msg_p->response);
- semop(semid, &respunlock, 1);
- // sem_wait(&msg_p->understood);
- semop(semid, &understoodlock, 1);
- } else { // treasure not found by current group
- if (found == 1 || nextarea > areas) { // if treasure was found before or no unsearched areas
- msg_p->type = MSG_TYPE_FINISH;
- msg_p->data = found;
- --groupsleft;
- // sem_post(&msg_p->response);
- semop(semid, &respunlock, 1);
- // sem_wait(&msg_p->understood);
- semop(semid, &understoodlock, 1);
- } else if (nextarea <= areas) {
- msg_p->type = MSG_TYPE_CONT;
- msg_p->area = nextarea++;
- // sem_post(&msg_p->response);
- semop(semid, &respunlock, 1);
- // sem_wait(&msg_p->understood);
- semop(semid, &understoodlock, 1);
- }
- }
- }
- }
- semctl(semid, 0, IPC_RMID, 0);
- shmdt(msg_p);
- if (shmctl(shmid, IPC_RMID, (struct shmid_ds *)0) == -1) {
- perror("shmctl");
- }
- puts("Пираты собрались и уплывают с острова.\n");
- } else { // child processes - groups
- // sem_wait(&msg_p->silverisfree);
- semop(semid, &silverlock, 1);
- msg_p->type = MSG_ASSIGN_AREA;
- msg_p->group = groupnum;
- // sem_post(&msg_p->groupsem);
- semop(semid, &groupunlock, 1);
- // sem_wait(&msg_p->response);
- semop(semid, &resplock, 1);
- int area = msg_p->area;
- printf("Группа %d отправилась искать клад на участке %d.\n", groupnum, area);
- // sem_post(&msg_p->understood);
- semop(semid, &understoodunlock, 1);
- while (running) {
- int searchtime = rand() % 3 + 1;
- int found;
- printf("Группа %d ищет клад на участке %d...\n", groupnum, area);
- sleep(searchtime);
- if (area == ans) {
- printf("Группа %d нашла клад на участке %d!\n", groupnum, area);
- found = 1;
- } else {
- printf("Группа %d не нашла клад на участке %d!\n", groupnum, area);
- found = 0;
- }
- // sem_wait(&msg_p->silverisfree);
- semop(semid, &silverlock, 1);
- msg_p->type = MSG_REPORT;
- msg_p->group = groupnum;
- msg_p->area = area;
- msg_p->data = found;
- // sem_post(&msg_p->groupsem);
- semop(semid, &groupunlock, 1);
- // sem_wait(&msg_p->response);
- semop(semid, &resplock, 1);
- if (msg_p->type == MSG_TYPE_FINISH) {
- if (msg_p->data == 1) {
- printf("Группа %d остается, так как сокровище найдено.\n", groupnum);
- found = 1;
- } else {
- printf("Группа %d остается, так как не осталось необысканных участков.\n", groupnum);
- found = 1;
- }
- } else if (msg_p->type == MSG_TYPE_CONT) {
- area = msg_p->area;
- printf("Группа %d отправляется искать клад на участке %d.\n", groupnum, area);
- }
- // sem_post(&msg_p->understood);
- semop(semid, &understoodunlock, 1);
- if (found == 1) {
- break;
- }
- }
- shmdt(msg_p);
- exit(0);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement