无法理解select()系统调用

时间:2012-09-28 19:38:10

标签: c linux posix file-descriptor fifo

我正在使用FIFO和select()系统命令运行测试。这个想法是:

  1. 进程1应该使用select()命令
  2. 等待来自FIFO的消息
  3. 如果没有消息进入,则进程一应该每隔5秒唤醒并说“暂无”
  4. 如果收到消息,则应该唤醒,打印消息,然后终止
  5. 所以这里是代码注意我正在进行错误检查以节省空间:

    //process 1's code
    int main()
    {
      int fd, ret;
      fd_set rfds;
      char buffer[100] = {0}; 
      char * myfifo = "/tmp/myfifo";
      struct timeval tv;
    
      tv.tv_sec = 5;  // 5 second sleep
      tv.tv_usec = 0;
    
      mkfifo(myfifo, 0666); //Make the fifo
    
      fd = open(myfifo, O_RDONLY);
      FD_ZERO(&rfds);    // clear the flags
      FD_SET(fd, &rfds); // set "read" on fd
    
      while((ret = select(fd+1, &rfds, NULL, NULL, &tv)) <= 0) //should be 1 when we're ready to read
      {
         FD_ZERO(&rfds);     //I believe we should clear/reset these every time?
         FD_SET(fd, &rfds);
         printf("Nothing yet...%d\n",ret);
         fflush(stdout);
      }
      n = read(fd, buffer, 100);
      printf("I got a read of %d bytes\nIt was %s\n",n, buffer);
    
      unlink(myfifo);
    
      return 0;
    }
    

    一旦我启动并运行了1,我等了好10秒然后开始第二个过程:

    //Process 2's code
    int main()
    {
      int fd, n, ret;
      fd_set rfds;
      char buffer[100] = {0};
      char * myfifo = "/tmp/myfifo";
      fd = open(myfifo, O_WRONLY);
    
      printf("What would you like to send?\n");
      fgets(buffer, 100, stdin);
      write(fd, buffer, strlen(buffer));
    
      close(fd);
      return 0;
    }
    

    我期待看到类似的东西:

    Nothing yet...0
    Nothing yet...0
    I got a read of X bytes
    It was <some string>
    

    相反,我没有看到任何内容,直到我输入内容并点击进入第二个进程,进程一正确返回字符串...但为什么循环不打印消息?

2 个答案:

答案 0 :(得分:6)

男人选择:

  

在Linux上,select()修改超时以反映未经过的时间   睡觉;大多数其他实现不会这样做。 (POSIX.1-2001   允许任何一种行为。)

因此你应该在循环中重新初始化tv。但这不是你问题的原因。原因是:

man mkfifo:

  

打开FIFO以便正常读取阻塞直到其他   进程打开相同的FIFO进行写入,反之亦然。

答案 1 :(得分:3)

当您使用Linux时,您可能希望在阅读器端的O_NONBLOCK电话中添加open()。有关详细信息,请参阅man 7 fifo