Re: how to run multiple processes from a single process?
In comp.os.linux.advocacy, mandydhaliwal@gmail.com
<mandydhaliwal@gmail.com>
wrote
on 31 Jul 2006 08:18:17 -0400
<1154329935.836825.170080@m73g2000cwd.googlegroups.com>:
Hi all,
I am porting a win32 c++ program on Linux which first reads a list of
processes and their paths from a file.Then this program should launch
all of thesese processes.
I tried to achieve this using fork() and execv() API calls. but
execv() method call is synchronous
and does not return untill user closes the child application or a
launch program error occurs.
Is there any other API / alternate solution available in Linux C++?
Thanks in advance.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
You appear slightly confused. The execl()/execv() is
indeed synchronous (in a way) but should be invoked *after*
the fork.
Herewith an example of more or less proper usage. This will
fork off NCHILDREN children and then wait for all of them.
This is not all that useful an example as written; the child
simply subinvokes a rather straightforward command line, but
modifications should be fairly obvious -- e.g., one could
take arguments from the argc/argv vector, or read them from a file
after some parsing.
This example should work in either C or C++, though with
C++ one might have to replace headers such as <stdio.h>
with <cstdio>. This example is intended for UNIX(tm),
Linux, and other Unix-like systems only.
---8< >8---
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
/* How many kids do we want? */
#define NCHILDREN 5
int main(int argc, char **argv)
{
pid_t child[NCHILDREN];
int i;
for(i = 0; i < NCHILDREN; i++)
{
child[i] = fork();
if(child[i] == 0)
{
/* I'm the child. Play in the sandbox; in this
case, just subinvoke /bin/ls with some args. */
char * lsvector[] = {"ls", "-l", "/usr/X11R6/bin",
(char *) NULL};
execv("/bin/ls", lsvector);
perror("execv"); /* should never get here unless execv fails! */
exit(-1);
}
else if ((int) child[i] < 0)
{
perror("fork"); /* something went wrong */
}
else
printf("Forked off child # %d with pid %d\n", i, child[i]);
}
/* At this point, we're in the parent and all kids are now
doing what kids do -- which in our case isn't much. */
for(i = 0; i < NCHILDREN; i++)
{
int chstatus = 0;
pid_t res = wait(&chstatus);
printf("A child exited with status %d (0x%x)\n", chstatus, chstatus);
printf("wait returned %d" ,child, res);
}
return 0; /* end program */
}
---8< >8---
Depending on needs, one can use fork() or vfork()
and wait(), wait3(), or waitpid(); the differences are
described in the relevant manpages. One advantage to using
wait(): the first dead child will return; they needn't die
in the order of their creation. vfork() is a bit of an
anachronism nowadays, but it was controversial at the time.
There's a lot of other things the kids can do, such as
close() and dup(). pipe() should be invoked by the
*parent* (the child will get a copy of the parent's
local variables/pages). One thing the child cannot do is
modify the parent's variables/pages, without such things
as mmap().
If one actually runs this program, expect a lot of slightly
scrambled output, as the children are going to output
to standard output without any sort of synchronization.
Synchronizing this output is tricky, though the parent
could set up pipes and use select() or poll() if need be.
Since this isn't really C++-specific, followups reset to COLA.
--
#191, ewill3@earthlink.net
Windows Vista. Because it's time to refresh your hardware. Trust us.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]