3

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

  1. select()进程一应该使用命令休眠等待来自 FIFO 的消息
  2. 如果没有消息进来,进程应该每 5 秒唤醒一次并说“还没有”
  3. 如果有消息进来,它应该唤醒,打印消息,然后终止

所以这里是代码注意我正在取出错误检查以节省空间:

//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 秒,然后我启动了进程 2:

//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>

相反,我什么也看不到,直到我输入一些内容并为进程二按回车键,进程一正确返回字符串......但为什么循环不打印消息?

4

2 回答 2

6

人选:

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

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

男人 mkfifo:

打开一个 FIFO 进行读取通常会阻塞,直到某个其他进程打开同一个 FIFO 进行写入,反之亦然。

于 2012-09-28T20:00:49.533 回答
3

当您在 Linux 上时,您可能希望添加O_NONBLOCKopen()读者端的调用中。详情请参阅man 7 fifo

于 2012-09-29T13:36:56.027 回答