C-如何将select()用于多个管道?

C-如何将select()用于多个管道?,c,select,pipe,C,Select,Pipe,我很难弄清楚select()在UNIX中是如何与管道一起工作的。我已经扫描了手册页好几次,但我不完全理解给定的定义 通过阅读手册页,我的印象是select()会让系统等待,直到给出的一个文件描述符能够从管道中读取(在我的例子中)而不阻塞 以下是我的一些大纲代码[已编辑]: int size, size2; fd_set rfds; struct timeval tv; char buffer[100]; char buffer2[100]; int retval; while(1) {

我很难弄清楚select()在UNIX中是如何与管道一起工作的。我已经扫描了手册页好几次,但我不完全理解给定的定义

通过阅读手册页,我的印象是select()会让系统等待,直到给出的一个文件描述符能够从管道中读取(在我的例子中)而不阻塞

以下是我的一些大纲代码[已编辑]:

int size, size2;
fd_set rfds;
struct timeval tv;
char buffer[100];
char buffer2[100];
int retval;

while(1)
{
    FD_ZERO(&rfds);
    FD_SET(fd[0], &rfds);
    FD_SET(fd2[0], &rfds);
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    retval = select(2, &rfds, NULL, NULL, &tv); //2 seconds before timeout

    if(retval == -1)
       perror("Select failed.\n");
    else if(retval)
    {
       size = read(fd[0], buffer, sizeof(buffer));
       if(size > 0)
          printf("Parent received from even: %s\n", buffer);
       size2 = read(fd2[READ], buffer2, sizeof(buffer2));
       if(size2 > 0)
          printf("Parent received from odd: %s\n", buffer2);
    }
    else
       printf("No data written to pipe in 2 last seconds.\n");
}
我这里有两根管子。两个子进程正在写入各自的管道,父进程必须同时读取它们

作为测试,我在每个管道上写一个小字符串。然后我尝试将它们读入,并使用select防止阻塞。唯一被打印出来的是来自均匀管道的字符串。它似乎仍在阻塞。我感到很沮丧,因为我觉得我在手册页上遗漏了一些东西。有人能告诉我我做错了什么吗

  • 您需要使用
    FD_ZERO()
    -请参见
    FD_集合之前的内容
  • 在选择之前设置超时值。通过
    选择
  • 返回
    select()
    后,0个或多个文件描述符将处于“就绪”状态,您可以在不阻塞的情况下读取它们。但是如果你读到一个还没有准备好的,它仍然会阻塞。现在您正在阅读所有这些内容,并且由于select()只等待其中一个准备就绪,因此很可能另一个不准备就绪


    你需要做的是弄清楚哪些已经准备好了,然后只从中读取()。
    select()
    的返回值将告诉您有多少已准备就绪,您可以使用
    ISSET()
    宏询问特定的一个是否已准备就绪。

    为什么在
    read
    之后要
    select
    ?现在我不是将RFD归零,我读到它只会清空文件描述符集,您不应将select的返回值保留为未选中状态。您必须手动将其归零,否则它将包含垃圾并扰乱对select的调用。将select的返回值保留为未选中状态也是一种糟糕的方式,因为如果select被信号中断,某些平台将不稳定,(选择可能需要特殊处理的will EINTR)@user931794-我不想太多地强调这个人不能阅读手册页。谢谢,这对我解释了很多。我是UNIX新手,所以我为我不能完全理解手册页而道歉。没问题!阅读手册页需要练习,因为手册页写得非常密集。这有助于将每一个单词都像im一样对待重要的,继续练习!