fork and exec many different processes, and obtain

2019-07-02 15:16发布

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?

3条回答
对你真心纯属浪费
2楼-- · 2019-07-02 15:27

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.

查看更多
Evening l夕情丶
3楼-- · 2019-07-02 15:42

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 */
}
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-07-02 15:49

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 */
查看更多
登录 后发表回答