C 从多个管道读取数据

C 从多个管道读取数据,c,linux,unix,C,Linux,Unix,我想做一个完全连接的网格拓扑模型。我有父母和孩子,他们用管道互相沟通。因此,每个进程都必须从多个管道读取数据。我不知道该怎么做 每个进程都有“本地id”作为增量(0-父进程、1、2、3等) 我创建了二维管道阵列。第一个阵列-目的地,第二个阵列-源: struct pipes_t { int rdwr[2]; }; struct dataIO_t { int processes; // number of processes int8_t lid; // prosecc l

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

每个进程都有“本地id”作为增量(0-父进程、1、2、3等)

我创建了二维管道阵列。第一个阵列-目的地,第二个阵列-源:

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;
}

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

您说您希望在不使用轮询、选择等的情况下读取多个文件描述符

正如您可能已经发现的,您不能简单地从几个管道中的一个读取数据并希望它能够工作,因为如果没有数据,您将阻塞

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

在伪代码中:

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

您说您希望读取多个文件描述符,而不使用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

您正在查找的函数是
轮询
;它等待几个文件描述符,并返回准备读取或写入的文件描述符。还有
select
,这是旧的,还有
epoll
,这有点复杂。@ColonelThirtyTwo我更新了这个问题,我不能使用这个函数swell,如果你不能使用合理的选项(和非标准的亲属),那么你需要使读取的文件描述符不阻塞(,
F_GETFL
F_SETFL
O_NONBLOCK
),并且您必须循环遍历每个文件描述符,以查看是否有任何数据可读取。您要查找的函数是
poll
;它等待多个文件描述符,并返回准备读取或写入的文件描述符。还有
select
,这是旧的,
epoll
,这是比较复杂的太复杂了。@ColonelThirtyTwo我更新了问题,我不能使用这个函数。如果你不能使用合理的选项(和非标准的亲属),那么你需要使读取文件描述符无阻塞(,
F_GETFL
F_SETFL
O_NONBLOCK
),您必须循环遍历每个文件描述符,以查看是否有任何数据可供读取。
setsockopt()
对管道描述符而不是套接字描述符有效吗?@JonathanLeffler:好的,我已经更新了我的伪代码,使用了
fcntl()
,这肯定有效(在一定程度上,伪代码可以有效!)。你应该使用
select
poll
而不是忙着等待。
setsockopt()
对管道描述符而不是套接字描述符有效吗?@JonathanLeffler:好的,我已经更新了我的伪代码,使用了
fcntl()
,这肯定有效(在一定程度上,伪代码可以有效!)。您应该使用
选择
轮询
,而不是忙着等待。