【问题标题】:How to use dup2/close correctly to connect these three processes?如何正确使用 dup2/close 连接这三个进程?
【发布时间】:2012-02-26 22:23:09
【问题描述】:

我正在尝试正确连接三个进程,以允许它们之间的进程间通信。我有一个进程,scanner,它获取父级的 STDIN,然后处理流中的单词。如果一个字长是奇数,它把它发送到一个进程,如果它是偶数,它把它发送到另一个进程。这些进程应该通过 STDIN(我假设)接收这些单词,然后通过 STDOUT 将一些信息输出回扫描仪进程。偶数/奇数的 STDOUT 应该重定向到扫描仪,然后扫描仪将读取(使用读取)然后输出/处理单词。这是一项学术练习,而不是实际练习。这是它的图片:

这是我的代码目前的样子。问题是我不确定要复制什么以及要关闭什么。一旦我弄清楚我应该很好去!任何建议将不胜感激。

文件描述符:

int scannertoeven[2]; int scannertoodd[2];
int eventoscanner[2]; int oddtoscanner[2];
//Pipe stuff here (ommitted)

代码:

 //Create the child processes
 if ((scanner_pid = fork())  == 0) {

      //We need the scanner pid so even and odd can send signals to it
      char pidofparent[sizeof(getpid())];
      sprintf(pidofparent, "%i", getpid());

      //Even stuff
      if ((even_pid = fork()) == 0) {
           close(scannertoodd[0]); close(scannertoodd[1]);
           close(oddtoscanner[0]); close(oddtoscanner[1]);

           //Not sure which ones to close
           close(scannertoeven[0]); close(scannertoeven[1]);
           close(eventoscanner[0]); close(eventoscanner[1]);


           //Correct?
           close(STDIN_FILENO);
           dup2(scannertoeven[0], STDIN_FILENO);
           close(STDOUT_FILENO);
           dup2(eventoscanner[1], STDOUT_FILENO);


          if(execl("./evenodd", "even", pidofparent,  NULL ) == -1) {
               printf("execl Error!");
               exit(1);
          }

     //Odd Stuff
     } else if ((odd_pid = fork()) == 0){
           close(scannertoeven[0]); close(scannertoeven[1]);
           close(eventoscanner[0]); close(eventoscanner[1]);

           //Not sure which ones to close
           close(scannertoodd[0]); close(scannertoodd[1]);
           close(oddtoscanner[0]); close(oddtoscanner[1]);

           //Correct?
           close(STDIN_FILENO);
           dup2(scannertoodd[0], STDIN_FILENO);
           close(STDOUT_FILENO);
           dup2(oddtoscanner[1], STDOUT_FILENO);

          if(execl("./evenodd", "odd", pidofparent,  NULL ) == -1) {
               printf("execl Error!");
               exit(1);
          } 


      //Actual Scanner
      } else {

           // Not sure which ones to close- this is very wrong
           close(scannertoeven[0]); close(scannertoeven[1]);
           close(eventoscanner[0]); close(eventoscanner[1]);
           close(scannertoodd[0]); close(scannertoodd[1]);
           close(oddtoscanner[0]); close(oddtoscanner[1]);

           //Not sure what to dup either
           dup2(scannertoodd[1], STDOUT_FILENO);
           dup2(scannertoeven[1], STDOUT_FILENO);
           if(execl("./scanner", "scanner", stoeven, stoodd, eventos, oddtos, NULL ) == -1) {
                printf("execl Error!");
                exit(1);
           }

           //Wait twice here, or three times in main?
           waitpid(odd_pid, &status2, 0);
           waitpid(even_pid, &status3, 0);
      }
 //Main
 } else {
      //Close Pipes
      close(scannertoodd[0]); close(scannertoeven[0]); close(eventoscanner[0]); close(oddtoscanner[0]);
      close(scannertoodd[1]); close(scannertoeven[1]); close(eventoscanner[1]); close(oddtoscanner[1]);
      //Wait for children to finish
      waitpid(scanner_pid, &status1, 0);
      printf("Done\n");
 }

【问题讨论】:

  • 无需关闭要替换的文件描述符。 dup2函数关闭第二个参数对应的描述符,然后将第一个参数对应的条目复制到第二个参数对应的条目中。

标签: c fork pipe dup2


【解决方案1】:

不确定逻辑。但是你使用dup2的方式不对。

“偶数”过程中的以下代码:

close(STDIN_FILENO);
dup2(scannertoeven[0], STDIN_FILENO);
close(STDOUT_FILENO);
dup2(eventoscanner[1], STDOUT_FILENO);

应该是:

dup2(scannertoeven[0], STDIN_FILENO);
// You should close scannertoeven[0], not STDIN. After this dup2, the even
// process will receive input from scannertoeven[0]
close(scannertoeven[0]);
// Note the the scannertoeven[0] is not "really" closed, just that the file
// is "attached" to STDIN

dup2(eventoscanner[1], STDOUT_FILENO);
// Same as above. After this dup2, all the even process's output will go
// to eventoscanner[1]
close(eventoscanner[1]);

与“奇数”过程相同。

这里是an example of dup2,供您参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-12
    • 2021-07-23
    • 2015-10-06
    • 2012-04-12
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 2017-11-16
    相关资源
    最近更新 更多