gpt4 book ai didi

C使用选择并从管道中读取

转载 作者:行者123 更新时间:2023-12-02 08:52:02 25 4
gpt4 key购买 nike

我有一个正在处理的程序,我使用 select 从管道中选择要读取的程序。

问题是我正在使用 if(FD_ISSET(pfd[i][0], &read_set)) 验证失败,因为 FD_ISSET 返回 0,但如果我尝试读取使用 read(pfd[i][0],&c,sizeof(c)) 它会正常工作,管道 pfd[0] 的内容与我想要的 pfd[1] 不同。

我想知道到底发生了什么,因为 FD_ISSET 返回 0 但我实际上可以从中读取内容

编辑

全局变量 CORES 将控制我创建多少进程下一段代码将创建管道并使用 FD_SET 设置位

for(i=0; i<CORES; i++)
{
if(pipe(pfd[i])==-1)
perror("Ocorreu um erro a criar um pipe");

FD_SET(pfd[i][0], &read_set);
}

read_set 是在 main() 启动后立即定义的。我在上面的代码之后使用 for() 来使用 fork() (x = CORES) 创建 x 个进程

然后这部分在父进程中运行:

    while (x<CORES){
int selec = select(pfd[CORES-1][0]+1, &read_set, NULL, NULL, NULL);

if(selec>0)
{
if(FD_ISSET(pfd[x][0], &read_set))
{
close(pfd[x][1]);

if(read(pfd[x][0],&c,sizeof(c))==-1)
perror("Ocorreu um erro a ler do pipe");

printf("c= %f \n",c);
c_final+=c;
x++;
}
else
printf("\nFile descriptor pfd[%d][0] is not set\n",x);

}
else if(selec == -1)
perror("Ocorreu um erro no select");
}

问题是 FD_ISSET(pfd[x][0], &read_set) 不会通过,因为它不是为 pfd[0] 设置的,但它可以为 pfd[1]反之亦然(因为我不知道它是否会因 0 或 1 而失败)

编辑 2:

select() 返回一个 int 表示 read_set 中文件描述符的数量。我将 CORES 设置为 2,因此它创建了 2 个进程和 2 个管道,并在 read_set 中设置了 2 位。我的 select() 正在返回 int 1。它是否也应该返回 int 2 或 0 个计数(所以它是 0 和 1 = 2)?

最佳答案

select 的第一个参数应该是 1+max_fd。虽然 pfd[CORES-1][0] 可能是最大的,但不能保证。您可以在填充 read_set 时计算最大的文件描述符,并将其用于您的 select 调用。

此外,您需要在每次调用 select 之前重新填充 read_set。所以while循环外面的for循环需要进来。实际上,最好把select移到外面,把从for循环开始的 block 围起来设置read_set,到while循环之后结束在另一个循环中 - 这样在每次选择返回时,您都可以处理所有已发出信号的描述符,而无需再次进入选择。


编辑:澄清我对循环的意思:你应该在每次 select 返回时检查所有描述符。但是您不能只调用 select 一次,因为不能保证所有答案都会立即准备就绪。所以你做这样的事情:

for (i=0; i != CORES; ++i)
{
// Call pipe() and populate pfd[i]
}

while (!finished) // Need a proper condition to terminate this loop
{
// Setup read_set
FD_ZERO(&read_set);
for (i=0; i != CORES; ++i)
{
FD_SET(pfd[i][0], &read_set);
// find max_fd here
}
// select here
if (select(max_fd+1, blahblah) > 0)
{
for (i=0; i != CORES; ++i) // This used to be while(x < CORES). But a for loop would do
{
// Check the fd, and process
}
}
else
{
// error in select
}
}

关于C使用选择并从管道中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7787620/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com