fork和exec许多不同的进程,并从每个进程获得结果

时间:2011-05-12 17:40:21

标签: c++ linux ipc exec fork

我已经设法从我的应用程序中分叉并执行不同的程序。我正在研究如何等待从exec调用的进程通过管道或stdout返回结果。但是,我可以使用单个fork进行一组进程,还是需要多次fork并再次调用相同的程序?我可以为每个不同的流程获得PID吗?我希望我的应用程序调用相同的程序,我目前正在调用多次但使用不同的参数:我想要一组8个进程运行同一个程序并通过管道返回结果。有人可以指点我正确的方向吗?我已经浏览了linux.die手册页,但它们在描述中非常简洁和神秘。是否有电子书或PDF格式我可以找到详细信息?谢谢!

pid_t pID = fork();
 if (pID == 0){
  int proc = execl(BOLDAGENT,BOLDAGENT,"-u","2","-c","walkevo.xml",NULL);
  std::cout << strerror(errno) << std::endl;
}

例如,如何通过PID控制哪个子(根据参数xml文件)获得了哪个结果(通过管道或标准输出),从而采取相应措施?我是否必须将子进程封装在一个对象中,然后从那里开始工作,还是可以将它们分组?

3 个答案:

答案 0 :(得分:6)

一个Fork系统调用只创建一个新进程(一个PID)。你应该组织一些数据结构(例如pids数组,管道父节点数组等),从主程序中做8个fork(每个孩子都会做exec)然后等待孩子。

在每个fork()之后,它会返回一个孩子的PID。您可以存储此pid和相关信息,如下所示:

#define MAX_CHILD=8
pid_t pids[MAX_CHILD];
int pipe_fd[MAX_CHILD];
for(int child=0;child<MAX_CHILD;child++) {
 int pipe[2];
 /* create a pipe; save one of pipe fd to the pipe_fd[child] */
 int ret;
 ret = fork();
 if(ret) { /* parent */ 
  /* close alien half of pipe */
  pids[child] = ret; /* save the pid */
 } else { /* child */
  /* close alien half of pipe */
  /* We are child #child, exec needed program */
  exec(...);
  /* here can be no more code in the child, as `exec` will not return if there is no error! */
 }
} 

/* there you can do a `select` to wait data from several pipes; select will give you number of fd with data waiting, you can find a pid from two arrays */

答案 1 :(得分:5)

起初它是令人费解的,但是当你调用fork()时,你似乎已经意识到了这一点:

  • 调用进程(“父”)是 基本上是重复的 操作系统和重复过程 成为“孩子” 拥有独特的PID;

  • fork()返回的值 call是:integer 0, 1 意思是 接收0返回的程序是 “儿童”;或者它是非零整数PID 分叉的孩子;和

  • 输入新的子进程 用于执行的调度队列。 父母仍然在安排中 队列并继续执行 之前。

这是(0 .xor。非0)从fork()返回告诉程序它在此时正在播放的角色 - 0返回,程序是子进程;返回的任何其他内容,程序是父进程。

如果扮演父角色的程序需要很多孩子,他必须分别对每个孩子进行fork();没有多个孩子共享一个fork()。

中间结果肯定可以通过管道发送。

至于用不同的参数调用每个孩子,实际上没有什么特别的事情要做:你可以确定,当孩子获得控制权时,他将拥有与父母完全相同的变量(副本)。因此,向孩子传达参数是父母设置他希望孩子操作的变量值的问题;然后调用fork()。


1 更准确地说:fork()返回一个pid_t类型的值,这些天与很多系统上的整数相同。

答案 2 :(得分:1)

自从我使用C / C ++以来已经有一段时间了,但有几点:

  • 维基百科fork-exec page提供了一个了解分叉和执行的起点。谷歌也是你的朋友。

  • 正如osgx的回答所说,fork()只能给你一个子进程,所以你必须调用它8次才能获得8个进程,然后每个进程必须执行另一个程序。

  • fork()将子进程的PID返回给主进程,将0返回给子进程,因此您应该能够执行以下操作:

int pid = fork();
if (pid == 0) {
  /* exec new program here */
} else {
  /* continue with parent process stuff */
}