Re: How do you get PID of a program called using system call?
by blakem (Monsignor) on Oct 08, 2001 at 12:12 UTC
|
Here is an example to get you started:
#!/usr/bin/perl -wT
use strict;
%ENV = (); # clean out the %ENV hash to prevent mischief
$ENV{PATH} = '/bin';
my @pids; # array for storing childr
+ens pids
my $cmd = 'sleep 2; echo "I am child $$"'; # command children will ex
+ecute
for (1..4) {
my $childpid = fork() or exec($cmd); # fork off a child
push(@pids,$childpid); # store the childs pid in @pid
+s
}
print "My Children: ", join(' ',@pids), "\n";
waitpid($_,0) for @pids; # wait for children to finish
print "Children are done\n";
-Blake
| [reply] [d/l] |
|
|
my $pid = fork();
if ($pid) {
push @pids, $pid;
}
elsif (defined $pid) {
exec($cmd);
die "Cannot exec '$cmd': $!\n";
}
else {
die "Cannot fork: $!\n"
}
Not catching the exec is potentially the most dangerous as the
child process then continues in the loop, just the same as the parent.
In this cas you would end up filling the process table. | [reply] [d/l] |
|
|
1 parent through the first time (creates 1 child)
1 parent 1 child the second time (creates 2 children)
2 parents 2 children the third time (creates 4 children)
4 parents 4 children the fourth time (creates 8 children)
So at most I see a possible 16 procs being active at once.... of course they might never exit due to the messed up @pids array, but thats another matter.
Again, thanks for the catch.
-Blake
| [reply] [d/l] [select] |
Re: How do you get PID of a program called using system call?
by virtualsue (Vicar) on Oct 08, 2001 at 12:39 UTC
|
To clarify, a bit, system does do a fork and exec to run
the program you specify, but it also waits for that
program to complete before returning control back to your
code. This means that you cannot use system() to (directly) get 4
processes running at the same time, and that you cannot
try to keep track of let alone control the processes created
by system(), because these processes are gone by the time
your program starts running again.
You already have a reply from blakem which provides
a piece of code demonstrating the use of fork & exec.
If you'd like more info, doing a Super Search for nodes containing 'fork' and
'exec' in the text comes up with a lot of useful looking
hits.
| [reply] [d/l] [select] |
Re: How do you get PID of a program called using system call?
by dws (Chancellor) on Oct 08, 2001 at 11:56 UTC
|
Invoking system() 4 times in a row won't give you 4 simultaneous processes unless whatever you're invoking does a fork(). Even then, you won't easily be able to get a pid unless somebody is kind enough to save it for you.
Your best bet might be to roll the fork()/exec() yourself, so that the parent process can get the child pid directly from fork().
| [reply] [d/l] [select] |
fork and wait example (the second)
by C-Keen (Monk) on Oct 08, 2001 at 20:41 UTC
|
Hi!
I would just like to redirect you to this node where I have already answered to this question. There is also sample code to get you started :-)Hope this helps, C-Keen | [reply] |
Re: How do you get PID of a program called using system call?
by monk_e_magic (Novice) on Oct 09, 2001 at 03:45 UTC
|
Thank you all for your reply, I found it very helpful.
However, when I mention about having 4 system calls that resulted in 4 pids, I mean the following(having them runnning in background):
my $cmd = "process_file -c arg1 -d arg2";
for(1..40)
{
if(!WINDOWS)
{
system("$cmd > /dev/null &");
}
else
{
system("sh -c \"$cmd > /tmp/null \"&");
}
}
as you can see, the above code will gives me 4 processes running in the back ground, but I have no control over those pids | [reply] [d/l] |
|
|
With this approach in mind, your best solution would be to iteration through the process table following execution of your system processes. Under *NIX, you would want to use Proc::ProcessTable (which I have written about before here). For Windows, you should take a look at either Win32::Process or Win32::ProcFarm.
Even so, I still think that you would find the best solution from pre-forking within your script, rather than launching system processes and detaching yourself from the controlling tty. This pre-forking approach would give you greater control, without the need to extraneous loops and control structures, of your spawned processes.
Ooohhh, Rob no beer function well without!
| [reply] |