从多个管道中读取数据

时间:2016-03-26 23:54:43

标签: c linux unix

我想做一个完全连接的网状拓扑模型。我有父母和孩子使用管道相互沟通。因此,每个进程都必须从多个管道中读取数据。我不知道该怎么做。

每个流程都有"本地ID"作为增量(0 - 父,1,2,3等)。

我创建了2d管道数组。第一个数组 - 目的地,第二个数组 - 来源:

struct pipes_t
{
   int rdwr[2];
};

struct dataIO_t
{
    int processes; // number of processes
    int8_t lid; // prosecc local id (0,1,2 etc)
    struct pipes_t pipes[MAX_LOCAL_ID+1][MAX_LOCAL_ID+1];
};

发送组播消息的功能:

int send(struct dataIO_t* data) {
    for(int i = 0; i < data->processes; i++)
        if(write(data->pipes[i][data->lid].rdwr[1], "Hello world\n", 12) != 1)
            return 1;
    return 0;
}

如何在没有线程的情况下从任何进程读取多个管道中的数据? 我尝试使用函数dup2来连接所有管道,但这不是一个好主意:

int receive(struct dataIO_t* data) {
    int fd[2];
    pipe(fd);

    const int BSIZE = 100;
    ssize_t nbytes;
    char buf[BSIZE];

    for(int i = 0; i < data->processes; i++)
        if(i != data->lid)
            if (dup2(data->pipes[data->lid][i].rdwr[0], fd[0]) == -1)
                return 1;

    nbytes = read(fd[0], buf, BSIZE);
    printf("Msg (%d): %s\n", data->lid, buf);

    return 0;
}

禁止:在本练习中,我无法使用pollselect和相同的功能。

1 个答案:

答案 0 :(得分:3)

你说你想要从多个文件描述符中读取而不使用poll,select等等。

正如您可能已经发现的那样,您不能简单地从多个管道中读取并希望它能够正常工作,因为如果没有数据,您将会阻止。

要解决此问题,您可以将要读取的所有文件描述符设置为非阻塞,这意味着如果没有可用数据,将立即返回读取。

在伪代码中:

for each fd in fds
    mode = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, mode | O_NONBLOCK)

forever
    for each fd in fds
        if read(fd)
            process data
    sleep a little to avoid 100% CPU usage