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

发布于 2024-11-07 01:07:12 字数 582 浏览 1 评论 0原文

我已经设法从我的应用程序中分叉并执行一个不同的程序。我目前正在研究如何等待 exec 调用的进程通过管道或标准输出返回结果。但是,我可以使用单个 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文件)获得了哪个结果(通过管道或stdout),从而采取相应的行动?我是否必须将子进程封装在一个对象中,并从那里开始工作,或者我可以将它们组合在一起吗?

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. 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? Can I get a PID for each different process ? 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. 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. Is there an ebook or pdf I can find for detailed information ? 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? Do I have to encapsulate children processes in an object, and work from there, or can I group them altogether?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

_蜘蛛 2024-11-14 01:07:12

一个 Fork 系统调用仅创建一个新进程(一个 PID)。您应该组织一些数据结构(例如 pid 数组、父级管道末端数组等),从主程序执行 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 */

One Fork syscall make only one new process (one PID). You should organize some data structures (e.g. 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.

After each fork() it will return you a PID of child. You can store this pid and associated information like this:

#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 */
灰色世界里的红玫瑰 2024-11-14 01:07:12

一开始这很令人费解,但你似乎明白了这一点,当你调用 fork( ) 时:

  • 调用进程(“父进程”)是
    基本上重复了
    操作系统和重复进程
    成为“孩子”
    具有自己唯一的 PID;

  • fork( ) 的返回值
    调用是:整数
    0,1 表示
    接收 0 返回的程序是
    “孩子”;或者是非零整数PID
    那个分叉的孩子;和

  • 新的子进程被输入
    执行的调度队列。
    家长仍保留在日程安排中
    排队并继续执行
    之前。

正是 fork( ) 返回的这个( 0 .xor. non-0 )告诉程序此时此刻正在扮演哪个角色 - 返回 0,程序是子进程;其他返回的内容,程序是父进程。

如果扮演父角色的程序想要很多孩子,他必须分别 fork( ) 每个孩子;不存在多个子进程共享一个 fork() 的情况。

中间结果当然可以通过管道发送。

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


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

It's mind-bending at first, but you seem to grasp that, when you call 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;

  • the returned value from the fork( )
    call is either: integer
    0,1 meaning that the
    program receiving the 0 return is the
    "child"; or it is the non-zero integer PID
    of that forked child; 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; 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; there's no such thing as multiple children sharing a 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( ).


1 More accurately: fork( ) returns a value of type pid_t, which these days is identical to an integer on quite a few systems.

霞映澄塘 2024-11-14 01:07:12

我已经有一段时间没有使用 C/C++ 了,但有几点:

  • 维基百科 fork-exec 页面 提供了了解分叉和执行的起点。 Google 也是您的朋友。

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

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

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

It's been a while since I've worked in C/C++, but a few points:

  • The Wikipedia fork-exec page provides a starting point to learn about forking and execing. 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.

  • 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:

int pid = fork();
if (pid == 0) {
  /* exec new program here */
} else {
  /* continue with parent process stuff */
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文