简体   繁体   English

平行叉管

[英]parallel fork pipe

void doWork(){

  int fd[2];
  int pret = pipe(fd);

  close(0);
  close(1);
  int dret = dup2(fd[1], 1);
  close(fd[1]);

  while(1){

    char buf[256];
    system("whoami");
    int rret = read(fd[0], buf, 256);

    if(/* something interesting */){
      return;
    }
  }
}

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

  int children = 2;

  for(unsigned work = 0; work < children; ++work){

    pid_t pid = fork();

    if(pid == 0){
      doWork();
      break;
    }
  }
  int status;
  wait(&status);

  return 0;
}

What is wrong with this example? 这个例子有什么问题? I'm trying to have each child process to call an external program, then read the output of that program from the pipe. 我试图让每个子进程都调用一个外部程序,然后从管道中读取该程序的输出。 My code only works when children is set to 1. 我的代码仅在孩子设置为1时有效。

EDIT: I'm trying to achieve task-parallelism with fork/pipes. 编辑:我正在尝试与叉子/管道实现任务并行性。 There is no communication between the parent and the child processes. 父进程与子进程之间没有通信。 Each child process executes an external program, reads the output, processes the output, and continues till the desired output is found. 每个子进程执行一个外部程序,读取输出,处理输出,然后继续直到找到所需的输出。

You need to create the pipe before you fork() , not after. 您需要在fork()之前而不是之后创建管道。 In your code, only the child process will have the pipe. 在您的代码中,只有子进程才具有管道。 You need both processes to share it. 您需要两个过程来共享它。

Eg.: 例如。:

int fd[2];
pid_t pid;

if (pipe(fd)) { /* TODO: handle error */ }

pid = fork();
if (pid < 0) { /* TODO: handle error */ }

if (pid == 0)
{
   /* We are the child.  Set fd[1] as stdout. */
   if (dup2(fd[1], 1)) { /* TODO: handle error */ }

   /* Close fd[0]; this process doesn't need it. */
   close(fd[0]);

   do_work();
   exit(0);
} 
else
{
   /* We are the parent... */
   /* Close the other guy's write fd. */
   close(fd[1]);

   /* Now read from fd[0] */
   /* Possibly waitpid() on child pid, etc. */
}

Also: I like to call fflush(stdout); 另外:我喜欢打电话给fflush(stdout); before I fork() . 在我fork()之前。 Otherwise you will observe weird behaviors with printf() . 否则,您将观察到printf()怪异行为。

You want to spawn child that will then execute some sub-process, parse it content, interpret it, and then exit ? 您想生成一个子代,该子代将执行一些子过程,解析其内容,对其进行解释,然后退出? If so, you need to fork twice for each task you want to create. 如果是这样,您需要为要创建的每个任务fork两次。 The first time to create the child that will handle the result of the subprocess, the second time to launch the subprocess. 第一次创建将处理子流程结果的子级,第二次启动子流程。

Something like that : 像这样:

void ExecuteCommandAndInterpretResult(const char* command)
{
    int fd[2];
    if (pipe(fd))
        exit(1);

    pid_t pid = fork();
    if (pid < 0)
        exit(1);

    if (pid == 0)
    {
        if (dup2(fd[1], 1))
            exit(1);

        close(fd[0]);
        execl(command, basename(command), NULL);
        exit(1);
    }
    else
    {
        int status;

        close(fd[1]);
        // do something with output from command

        wait(&status);
        exit(0);
    }
}

#define CHILDREN 2
int main()
{
    unsigned int i;
    pid_t pids[CHILDREN];

    for (i = 0; i < CHILDREN; i ++)
    {
        pids[i] = fork();
        if (pids[i] < 0)
        {
            // TODO: handle error
        }
        else if (pids[i] == 0)
        {
            ExecuteCommandAndInterpretResult("/usr/bin/ls");
            exit(0);
        }
    }

    for (i = 0; i < CHILDREN; i ++)
    {
        if (pids[i] > 0)
        {
            int status;
            waitpid(pids[0], &status, 0);
        }
    }

    return 0;
}

您是否考虑过在孩子中使用popen()执行whoami

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM