Harrowmont
@Harrowmont
C/C++ под Linux, Python, bash

Как правильно организовать двунаправленное соединение между процессами?

Здравствуйте. Написал простую программу для организации двунаправленного соединения между потоками, руководствуясь Шоном Уолтоном (глава 7, рис. 7.3). Перед тем, как запустить программу открывается 2 окна терминала, где можно увидеть процесс взаимодействия. Программа представляет собой 2 процесса: Предок владеет терминалом /dev/pts/2, потомок -- /dev/pts/1. Предок и потомок, с помощью механизма inotify, осуществляют мониторинг файлов pinp и dinp соответственно. Как только в какой-либо из данных файлов произошла запись данные записываются в канал (pipe) и отправляются соседнему процессу для вывода в его терминал. Однако программа работает не правильно, а именно как только родительский inotify сработал, то начинает постоянно срабатывать poll, будто осуществляется запись в файл (чего не происходит). При попытке отправить что-нибудь в канал от соседа -- ничего не происходит. Почему? Помогите, пожалуйста.
#include <unistd.h>
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <fcntl.h>

#include <sys/inotify.h>

int main(int argc, char **argv)
{
    int fd1[2];
    int fd2[2];

    pipe(fd1);
    pipe(fd2);

    int pid;
    if( (pid = fork()) < 0 ){
        perror("Error while calling fork()");
        return 1;
    }
    else if(pid == 0){
        // CHILD
        close(fd1[0]);
        close(fd2[1]);

        dup2(fd2[0], 0);
        close(fd2[0]);

        dup2(fd1[1], 1);
        close(fd1[1]);

        int fileInp = open("./dinp.txt",  O_RDONLY);
        int fileOut = open("/dev/pts/1",  O_WRONLY);

        int dinp;
        dinp = inotify_init();
        if(dinp == -1){
            perror("inotify not init");
            exit(EXIT_FAILURE);
        }
        int wdinp;
        wdinp = inotify_add_watch(dinp, "./dinp.txt", IN_MODIFY);
        if(wdinp == -1){
            perror("inotify_add_watch");
            exit(EXIT_FAILURE);
        }

        lseek(fileInp, 0, SEEK_END);

        struct pollfd fds[2];
        fds[0].fd = dinp;
        fds[0].events = POLLIN;
        fds[1].fd = 0;
        fds[1].events = POLLIN;

        while(true){
            int ret = poll(fds, 2, -1);
            if(ret == -1){
                perror("poll error");
                return 1;
            }
            if(fds[0].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fileInp, c, BUFSIZ)) != 0)
                    write(1, c, len);
            }
            if(fds[1].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fds[1].fd, c, BUFSIZ)) != 0)
                    write(fileOut, c, len);
            }
        }
    }
    else{
        // PARENT
        close(fd1[1]);
        close(fd2[0]);

        fd1[1] = fd2[1];

        int fileInp = open("./pinp.txt",  O_RDONLY);
        int fileOut = open("/dev/pts/2",  O_WRONLY);

        int pinp;
        pinp = inotify_init();
        if(pinp == -1){
            perror("inotify not init");
            exit(EXIT_FAILURE);
        }
        int wpinp;
        wpinp = inotify_add_watch(pinp, "./pinp.txt", IN_MODIFY);
        if(wpinp == -1){
            perror("inotify_add_watch");
            exit(EXIT_FAILURE);
        }

        lseek(fileInp, 0, SEEK_END);

        struct pollfd fds[2];
        fds[0].fd = pinp;
        fds[0].events = POLLIN;
        fds[1].fd = fd1[0];
        fds[1].events = POLLIN;

        while(true){
            int ret = poll(fds, 2, -1);

            if(ret == -1){
                perror("poll error");
                return 1;
            }
            if(fds[0].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fileInp, c, BUFSIZ)) != 0){
                    write(fd1[1], c, len);
                }
            }
            if(fds[1].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fds[1].fd, c, BUFSIZ)) != 0){
                    write(fileOut, c, len);
                }
            }
        }
    }
    return 0;
}
  • Вопрос задан
  • 941 просмотр
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
http://dilbert.com/strip/1998-08-24
как только родительский inotify сработал, то начинает постоянно срабатывать poll

Вы нигде не читаете из файла pinp, поэтому после первого срабатывания poll срабатывает без остановки.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы