简体   繁体   English

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

[英]fork and exec many different processes, and obtain results from each one

I have managed to fork and exec a different program from within my app. 我已经设法从我的应用程序中分叉并执行不同的程序。 I'm currently working on how to wait until the process called from exec returns a result through a pipe or stdout. 我正在研究如何等待从exec调用的进程通过管道或stdout返回结果。 However, can I have a group of processes using a single fork, or do I have to fork many times and call the same program again? 但是,我可以使用单个fork进行一组进程,还是需要多次fork并再次调用相同的程序? Can I get a PID for each different process ? 我可以为每个不同的流程获得PID吗? I want my app to call the same program I'm currently calling many times but with different parameters: I want a group of 8 processes of the same program running and returning results via pipes. 我希望我的应用程序调用相同的程序,我目前正在调用多次但使用不同的参数:我想要一组8个进程运行同一个程序并通过管道返回结果。 Can someone please point me to the right direction please ? 有人可以指点我正确的方向吗? I've gone through the linux.die man pages, but they are quite spartan and cryptic in their description. 我已经浏览了linux.die手册页,但它们在描述中非常简洁和神秘。 Is there an ebook or pdf I can find for detailed information ? 是否有电子书或PDF格式我可以找到详细信息? Thank you! 谢谢!

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

For example, how can I control by PID which child (according to the parameter xml file) has obtained which result (by pipe or stdout), and thus act accordingly? 例如,我如何通过PID控制哪个子(根据参数xml文件)获得了哪个结果(通过管道或标准输出),从而采取相应的行动? Do I have to encapsulate children processes in an object, and work from there, or can I group them altogether? 我是否必须将子进程封装在一个对象中,然后从那里开始工作,还是可以将它们完全分组?

One Fork syscall make only one new process (one PID). One Fork系统调用只进行一个新进程(一个PID)。 You should organize some data structures (eg array of pids, array of parent's ends of pipes, etc), do 8 fork from main program (every child will do exec ) and then wait for childs. 你应该组织一些数据结构(例如pid数组,管道父节点数组等),从主程序中做8个fork(每个孩子都会执行exec )然后等待孩子。

After each fork() it will return you a PID of child. 在每个fork()之后,它将返回一个孩子的PID。 You can store this pid and associated information like this: 您可以存储此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 */

It's mind-bending at first, but you seem to grasp that, when you call fork( ): 一开始它是令人费解的,但是当你调用fork()时,你似乎已经意识到了这一点:

  • the calling process (the "parent") is essentially duplicated by the operating system and the duplicate process becomes the "child" with a unique PID all its own; 调用进程(“父”)基本上由操作系统复制,并且复制进程成为具有唯一PID的“子”;

  • the returned value from the fork( ) call is either: integer 0, 1 meaning that the program receiving the 0 return is the "child"; 从fork()调用返回的值可以是:整数0,1,意味着节目接收的0返回是“子”; or it is the non-zero integer PID of that forked child; 或者是分叉子的非零整数PID; and

  • the new child process is entered into the scheduling queue for execution. 新的子进程被输入调度队列以供执行。 The parent remains in the scheduling queue and continues to execute as before. 父节点保留在调度队列中,并继续像以前一样执行。

It is this ( 0 .xor. non-0 ) return from fork( ) that tells the program which role it's playing at this instant -- 0 returned, program is the child process; 从fork()返回这个(0 .xor。非0)告诉程序它在这个时刻正在播放哪个角色 - 0返回,程序是子进程; anything else returned, program is the parent process. 返回的任何其他内容,程序是父进程。

If the program playing the parent role wants many children, he has to fork( ) each one separately; 如果播放父角色的程序需要很多孩子,他必须分别fork()每个孩子; there's no such thing as multiple children sharing a fork( ). 没有多个孩子共享fork()这样的东西。

Intermediate results certainly can be sent via a pipe. 中间结果当然可以通过管道发送。

As for calling each child with different parameters, there's really nothing special to do: you can be sure that, when the child gets control, he will have (copies of) exactly the same variables as does the parent. 至于用不同的参数调用每个孩子,实际上没有什么特别的事情要做:你可以确定,当孩子获得控制权时,他将拥有与父母完全相同的变量(副本)。 So communicating parameters to the child is a matter of the parent's setting up variable values he wants the child to operate on; 因此,向孩子传达参数是父母设置他希望孩子操作的变量值的问题; and then calling fork( ). 然后调用fork()。


1 More accurately: fork( ) returns a value of type pid_t , which these days is identical to an integer on quite a few systems. 1更准确:fork()返回一个pid_t类型的值,这些天在很多系统上都是一个整数。

It's been a while since I've worked in C/C++, but a few points: 自从我使用C / C ++以来已经有一段时间了,但有几点:

  • The Wikipedia fork-exec page provides a starting point to learn about forking and execing. Wikipedia fork-exec页面提供了一个了解分叉和执行的起点。 Google is your friend here too. 谷歌也是你的朋友。

  • As osgx's answer says, fork() can only give you one subprocess, so you'll have to call it 8 times to get 8 processes and then each one will have to exec the other program. 正如osgx的回答所说,fork()只能给你一个子进程,所以你必须调用它8次才能获得8个进程,然后每个进程必须执行另一个程序。

  • fork() returns the PID of the child process to the main process and 0 to the subprocess, so you should be able to do something like: fork()将子进程的PID返回给主进程,将0返回给子进程,因此您应该能够执行以下操作:

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

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

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