0

我有一个使用 fork() 和 pipe() 的标准程序,目的是在子进程中对第三方程序进行 system() 调用并将输出重定向到父进程。我发现如果我这样做,父进程永远无法检测到子进程已关闭管道,因此它永远无法从调用 read() 的 while 循环中退出。

当我用一些其他通用系统调用(如 system("ls -l"))替换对第三方程序的 system() 调用时,问题就消失了。使用影响该程序的 system() 调用第三方程序可能存在哪些潜在问题?

#include <iostream> 
#include <fstream>
#include <stdlib.h>//system
#include <sys/wait.h>

int main(int argc, char **argv){

  //setup pipe
  int pipeid_L1[2];
  pipe(pipeid_L1);

  pid_t pid_L1;
  pid_L1 = fork(); 
  if( pid_L1==-1 ){
    throw std::logic_error("Fork L1 failed");
  }
  else if(pid_L1 ==0){//L1 child process
    dup2(pipeid_L1[1],STDOUT_FILENO);//redirect standard out to pipe
    close(pipeid_L1[0]); //child doesn't read
    system( ... some program ... ); //making the system call to a third party program
    close(pipeid_L1[1]); 
    exit(0);
  }
  else{ 

    //setup pipe  
    close(pipeid_L1[1]);      

    int buf_size=64;
    char L1_buf[buf_size];

    while( read(pipeid_L1[0],L1_buf,buf_size)){ //this while loop never exits if I make the system call to the third party program
      ... do stuff here ...
    }


  }
  exit(EXIT_SUCCESS);
}
4

1 回答 1

1

问题是当所有其他进程关闭管道的写入端时,父级只会看到 EOF。有三个相关的进程——你派生的孩子,系统派生和执行的外壳,以及你运行的实际程序。前两个在程序实际退出之前不会关闭管道的末端,因此在发生这种情况并且所有进程都退出之前,父级不会看到 EOF。

如果您希望父程序在程序关闭其标准输出后立即看到 EOF,而不是等到它退出,您需要通过使用exec而不是system.

或者,您可以使用popenwhich 为您完成所有需要的 fork/pipe/exec。

于 2013-04-25T00:14:22.993 回答