C 从命名管道读取

C 从命名管道读取,c,pipe,named-pipes,C,Pipe,Named Pipes,我必须编写一个程序来监视两个命名管道,并打印通过其中一个管道发送的信息 当其中一个管道的写入端关闭时,程序将检测到此情况并再次关闭和打开管道 这是我到目前为止写的: #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #incl

我必须编写一个程序来监视两个命名管道,并打印通过其中一个管道发送的信息

当其中一个管道的写入端关闭时,程序将检测到此情况并再次关闭和打开管道

这是我到目前为止写的:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define BUF_SIZE 200

int
main(void)
{
   fd_set rfds;
   struct timeval tv;
   int retval;
   ssize_t n_read;
   char buf[BUF_SIZE];

   /* Open pipes */
   int tuberia1_fd = open("tuberia1",O_RDONLY);
   int tuberia2_fd = open("tuberia2",O_RDONLY);

   while(1){
       /* Watch stdin (fd 0) to see when it has input. */
       FD_ZERO(&rfds);
       FD_SET(0, &rfds);

       /* Wait for an indefinite amount of time. */
       tv.tv_sec = 0;
       tv.tv_usec = 0;

       retval = select(2, &rfds, NULL, NULL, &tv);
       /* Don't rely on the value of tv now! */

       if (retval == -1)
           perror("select()");
           exit(EXIT_FAILURE);

       if(FD_ISSET(tuberia1_fd, &rfds)){
           n_read = read(tuberia1_fd, &buf, BUF_SIZE);
           if (n_read == 0){
               close(tuberia1_fd);
               tuberia1_fd = open("tuberia1", O_RDONLY);
           }else{
               buf[n_read] = '\0';
               printf("tuberia1: %s", buf);
           }
       } else if (FD_ISSET(tuberia2_fd, &rfds)){
           n_read = read(tuberia2_fd, &buf, BUF_SIZE);
           if (n_read == 0){
               close(tuberia2_fd);
               tuberia2_fd = open("tuberia2", O_RDONLY);
           }else{
               buf[n_read] = '\0';
               printf("tuberia2: %s", buf);
           }
       }
   }
}

它仍然不起作用。在GDB下运行它表明程序永远不会超过第一个
open

您需要对您实际感兴趣的文件描述符使用
FD\u SET
,即
tuberia1\u FD
tuberia2\u FD

所以有点像

while (1) {
  FD_ZERO(&rfds);
  FD_SET(tuberia1_fd, &rfds);
  FD_SET(tuberia2_fd, &rfds);
  int max;
  if (tuberia1_fd > tuberia2_fd) {
    max = tuberia1_fd;
  } else {
    max = tuberia2_fd;
  }
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  retval = select(max + 1, &rfds, NULL, NULL, &tv);

如果您在调试器中运行程序,我很有信心您会看到执行
echo
命令会导致您的程序通过第一个
open()
,而在第二个
上被阻塞。捕捉得好!然而,我已经解决了这个问题,但仍然不起作用。您能否进一步阐述一下您所说的“不起作用”
?你能在调试器中一步一步地检查代码,找到if失败或执行意外操作的点吗?当我使用GBD运行它时,程序在第一次
打开
调用时会卡住
while (1) {
  FD_ZERO(&rfds);
  FD_SET(tuberia1_fd, &rfds);
  FD_SET(tuberia2_fd, &rfds);
  int max;
  if (tuberia1_fd > tuberia2_fd) {
    max = tuberia1_fd;
  } else {
    max = tuberia2_fd;
  }
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  retval = select(max + 1, &rfds, NULL, NULL, &tv);