微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

同时读取命名和未命名管道的问题

如何解决同时读取命名和未命名管道的问题

我试图让一个进程从命名管道和一些未命名管道中读取。首先我有一个主进程,它创建一个子进程,然后初始化一个命名管道,等待来自终端的数据发送到命名管道:

    int main(){
  signal(SIGINT,sigint);

  if(fork()==0){
    newProcess();
    exit(0);
  }



  unlink(PIPE_NAME);

  printf("Creating named pipe.\n");
  if ((mkfifo(PIPE_NAME,O_CREAT|O_EXCL|0600)<0) && (errno!= EEXIST)) {
    perror("Cannot create pipe: ");
    exit(0);
  }
  printf("Named pipe created.\n");


  int named_pipe_fd;
  printf("opening named pipe.\n");
  if ((named_pipe_fd = open(PIPE_NAME,O_WRONLY)) < 0) {
    perror("Cannot open pipe for writing: ");
    exit(0);
  }
  printf("Named pipe open.\n");


  char toSend[512];
  //Sends data via the NAMED pipe to our child process
  while(1){
    scanf("%[^\n]%*c",toSend);
    printf("[RaceSimulator] Sending (%s)\n",toSend);
    write(named_pipe_fd,toSend,sizeof(toSend));
  }


  return 0;
}

子进程打开命名管道进入读取模式,并创建一个充满文件描述符的数组,等待信息到来。现在我还没有创建未命名的管道,因此它们在数组中的值为 -1:

void newProcess(){


  //Initialize the pipes
  for(int i=0;i<MAX;i++){
    pipes[i]=-1;
  }

  //OPEN NAMED PIPE FOR READING
  int fd;
  if ((fd= open(PIPE_NAME,O_RDONLY)) < 0) {
    perror("Cannot open pipe for reading: ");
    exit(0);
  }


  pipes[0]=fd;
  char received[512];

  //Loop that waits for data to appear in the pipes
  while(1){

    fd_set read_set;
    FD_ZERO(&read_set);

    for (int channel=0;channel<MAX;channeL++) {
      FD_SET(pipes[channel],&read_set);
    }

    if (select(pipes[MAX-1]+1,&read_set,NULL,NULL) > 0 ) {

       if (FD_ISSET(pipes[0],&read_set)) {

          read(pipes[0],received,sizeof(received));
          printf("[Named pipe] Received %s.\n",received);

      }

      //Unamed pipes are still not created!
      for (int channel=1;channel<MAX;channeL++) {

        if (FD_ISSET(pipes[channel],&read_set)) {

          read(pipes[channel],sizeof(received));
          printf("[Unamed pipe] Received %s.\n",received);

        }
      }
    }
  }
}

问题是,我在终端上写的时候,终端只回写了主进程的printf。这意味着没有任何东西被发送到命名管道的另一端,但我不明白为什么。这是整个代码(注意:这是一个片段,出于法律原因我不能发送原始代码,我也知道我在这个片段中包含了太多内容:P):

#define PIPE_NAME "pipe"
#define MAX 5

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>


int pipes[MAX];

void clean(){
  unlink(PIPE_NAME);
}

void sigint(int signum){
  clean();
  exit(0);
}


void newProcess(){


  //Initialize the pipes
  for(int i=0;i<MAX;i++){
    pipes[i]=-1;
  }

  //OPEN NAMED PIPE FOR READING
  int fd;
  if ((fd= open(PIPE_NAME,received);

        }
      }
    }
  }
}


int main(){
  signal(SIGINT,sizeof(toSend));
  }


  return 0;
}

任何帮助将不胜感激!

解决方法

select 的第一个参数应该是集合中编号最高的文件描述符。由于您已将它们全部初始化为 -1,除了第零个,此调用:

select(pipes[MAX-1]+1,&read_set,NULL,NULL)

不会工作。您需要将其更改为:

select(fd+1,NULL)

或者,一旦你创造了其他人,就是其中最高的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。