Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- int main()
- {
- int fd[2], result;
- size_t rw;
- char resstring[64];
- int semid;
- key_t key;
- if((key = ftok("p4.c", 0)) < 0) {
- printf("Can't generate key\n");
- exit(-1);
- }
- if((semid = semget(key, 3, 0666 | IPC_CREAT)) < 0){
- printf("Can't get semid\n");
- exit(-1);
- }
- //Семафор 0 - признак наличия данных в пайпе, 0 - есть, 1 - нет
- //Семафор 1 - признак очереди родителя, 0 - да, 1 - нет
- //Семафор 2 - признак очереди потомка, 0 - да, 1 - нет
- struct sembuf mybuf;
- mybuf.sem_op = 1;
- mybuf.sem_flg = 0;
- mybuf.sem_num = 0;
- //Устанавливаем отсутствие данных в пайпе
- semop(semid, &mybuf, 1);
- mybuf.sem_num = 2;
- //Увеличиваем семафор 2 на 1, чтобы первым действовал родитель
- semop(semid, &mybuf, 1);
- mybuf.sem_op = 0;
- if(pipe(fd) < 0) {
- printf("Can't create pipe\n");
- exit(-1);
- }
- result = fork();
- if(result <0) {
- printf("Can't fork child\n");
- exit(-1);
- } else if (result > 0) {
- //parent
- char *msg[] = {
- "Parent message 1",
- "Parent message 2",
- "Parent message 3",
- "Parent message 4",
- "Parent message 5"
- };
- int s = 0, r = 0, hd = 0;
- while(1) {
- //Пытаемся занять канал
- mybuf.sem_num = 1;
- mybuf.sem_op = 0;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Parent: failed to wait sem 1\n");
- perror("Parent");
- exit(-1);
- }
- //Заняли
- //Проверяем, есть ли данные в канале
- mybuf.sem_op = 0;
- mybuf.sem_flg = IPC_NOWAIT;
- mybuf.sem_num = 0;
- if(!(semop(semid, &mybuf, 1) < 0)) {
- //Есть данные в канале
- //Получаем и пишем
- printf("Parent: Got message\n");
- read(fd[0], resstring, 64);
- printf("MSG_PARENT: %s\n", resstring);
- r++;
- hd = 1;
- } else {
- hd = 0;
- }
- //Посылаем данные, если еще не выслали все
- if(s < 5) {
- write(fd[1], msg[s], strlen(msg[s])+1);
- s++;
- printf("Parent: Sent message\n");
- if(!hd) {
- //Если в канале не было данных
- mybuf.sem_op = -1;
- mybuf.sem_flg = 0;
- mybuf.sem_num = 0;
- semop(semid, &mybuf, 1);
- printf("Parent: No data in pipe, set sem 0 to 0\n");
- }
- } else if(hd) {
- //Прочитали, но не написали, а данные в канале были
- mybuf.sem_op = 1;
- mybuf.sem_flg = 0;
- mybuf.sem_num = 0;
- semop(semid, &mybuf, 1);
- printf("Parent: Has data, but nothing to sent, set sem 0 to 1\n");
- }
- //Освобождаем канал
- mybuf.sem_op = 1;
- mybuf.sem_num = 1;
- mybuf.sem_flg = 0;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Parent: failed to set sem 1 to 1\n");
- perror("Parent");
- exit(-1);
- }
- //Передаем ход потомку
- mybuf.sem_num = 2;
- mybuf.sem_op = -1;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Parent: failed to set sem 2 to 0\n");
- perror("Parent");
- exit(-1);
- }
- if(r == 5 && s == 5)
- break;
- }
- printf("Parent exit\n");
- //size = write(fd[1], "Hello, world!", 14);
- //printf("Parent exit, writed %d\n", size);
- } else {
- //child
- char *msg[] = {
- "Child message 1",
- "Child message 2",
- "Child message 3",
- "Child message 4",
- "Child message 5"
- };
- //size = read(fd[0], resstring, 14);
- int s = 0, r = 0, hd = 0;
- while(1) {
- //Пытаемся занять канал (потомок)
- mybuf.sem_num = 2;
- mybuf.sem_op = 0;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Child: failed to wait sem 2\n");
- perror("Child");
- exit(-1);
- }
- //Заняли
- //Проверяем, есть ли данные в канале
- mybuf.sem_op = 0;
- mybuf.sem_flg = IPC_NOWAIT;
- mybuf.sem_num = 0;
- if(!(semop(semid, &mybuf, 1) < 0)) {
- //Есть данные в канале
- //Получаем и пишем
- printf("Child: Got message\n");
- read(fd[0], resstring, 64);
- printf("MSG_CHILD: %s\n", resstring);
- r++;
- hd = 1;
- } else {
- hd = 0;
- }
- //Посылаем данные, если еще не выслали все
- if(s < 5) {
- write(fd[1], msg[s], strlen(msg[s])+1);
- s++;
- printf("Child: Sent message\n");
- if(!hd) {
- //Если в канале не было данных
- mybuf.sem_op = -1;
- mybuf.sem_flg = 0;
- mybuf.sem_num = 0;
- semop(semid, &mybuf, 1);
- printf("Child: No data in pipe, set sem 0 to 0\n");
- }
- } else if(hd) {
- //Прочитали, но не написали, а данные в канале были
- mybuf.sem_op = 1;
- mybuf.sem_flg = 0;
- mybuf.sem_num = 0;
- semop(semid, &mybuf, 1);
- printf("Child: Has data, but nothing to sent, set sem 0 to 1\n");
- }
- //Освобождаем канал
- mybuf.sem_op = 1;
- mybuf.sem_num = 2;
- mybuf.sem_flg = 0;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Child: failed to set sem 2 to 1\n");
- perror("Child");
- exit(-1);
- }
- //Передаем ход родителю
- mybuf.sem_num = 1;
- mybuf.sem_op = -1;
- if(semop(semid, &mybuf, 1) < 0) {
- printf("Child: failed to set sem 1 to 0\n");
- perror("Child");
- exit(-1);
- }
- if(r == 5 && s == 5)
- break;
- }
- printf("Child exit\n");
- exit(0);
- //printf("%s\n",resstring);
- }
- waitpid(result, &rw, 0);
- printf("Sem's removed\n");
- semctl(semid, 0, IPC_RMID, 0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement