繁体   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;
}

这个例子有什么问题? 我试图让每个子进程都调用一个外部程序,然后从管道中读取该程序的输出。 我的代码仅在孩子设置为1时有效。

编辑:我正在尝试与叉子/管道实现任务并行性。 父进程与子进程之间没有通信。 每个子进程执行一个外部程序,读取输出,处理输出,然后继续直到找到所需的输出。

您需要在fork()之前而不是之后创建管道。 在您的代码中,只有子进程才具有管道。 您需要两个过程来共享它。

例如。:

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. */
}

另外:我喜欢打电话给fflush(stdout); 在我fork()之前。 否则,您将观察到printf()怪异行为。

您想生成一个子代,该子代将执行一些子过程,解析其内容,对其进行解释,然后退出? 如果是这样,您需要为要创建的每个任务fork两次。 第一次创建将处理子流程结果的子级,第二次启动子流程。

像这样:

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