1

昨天我发现select,这是一个非常有用的工具,但我无法使其工作。这是我的总代码的一部分:

/* Code here */
FD_ZERO(&fifo_set);
printf("%d\n", num_proc);
for(i = 0; i < num_proc; ++i)
    FD_SET(proc[i].fifowfd, &fifo_set);

/* More code here */
while(1)
{
    if(select(FD_SETSIZE, &fifo_set, NULL, NULL, NULL) < 0)
    {
        log_event(5, "Could not block.");
        exit(1);
    }
    printf("FD_SETSIZE: %d\n", FD_SETSIZE);
    for(i = 0; i < FD_SETSIZE; ++i)
        printf("ISSET %d: %d\n", i, FD_ISSET(i,&fifo_set));

    log_event(1, "Actions to be done.");
/* More code */

数组 proc 是一个进程数组,给定它的 PID 和一个读写 FIFO。FIFO 的文件描述符被检查,并且是有效的。问题是:有 3 个进程(num_proc),fifowfd 值为 5、7 和 9。但是当我打印所有 FD_ISSET 时,似乎只有 5 个已注册并有数据,但三个都有数据。FD_SETSIZE 的值为 1024。

正如@mux 所指出的,这个 FIFO 被命名为“用于写入的 FIFO”。问题是,我有一堆“name.r.fifo”和“name.w.fifo”,它们从进程的一侧代表“用于读/写的FIFO”。我展示的代码是来自控制器的代码,它读入“.w.fifo”,并写入“.r.fifo”。

我错过了什么吗?

4

2 回答 2

2

的第一个参数select()是编号最高的文件描述符加 1:

select(highest_fd+1, &fifo_set, NULL, NULL, NULL);

注意:fd 集将包含 select 返回后“准备好”的描述符,如果您想再做一次,您应该重新设置 fdsselect()

于 2013-08-11T10:29:55.203 回答
2

如果调用 select 时所有描述符都没有数据,它将阻塞,直到至少有一个描述符准备好读取。可能,描述符 5 是第一个被检查的,并且在其他管道有任何数据要读取之前选择退出。

您还应该检查 select 的实际结果,因为它包含它设置的位数。

于 2013-08-11T10:40:00.677 回答