Home > Archive > PERL Beginners > October 2006 > Non-blocking child process
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Non-blocking child process
|
|
| Kim Helliwell 2006-10-19, 3:59 am |
| I'm not even sure the title is the appropriate terminology. What I am
trying to do is fork a process that receives data from the parent, but,
once the data is received, the parent can go on and do whatever it wants
(and likewise the child). How do I arrange for the child process to be
detached once the data is sent to it?
Put another way, I do NOT want the parent to block waiting for the child
to exit.
Here is (in summary) the code I am using (which was adapted from section
16.10 of the Perl Cookbook):
if($pid = open(CHILD, "|-"))
{
CHILD->autoflush(1);
$sprm = $type . "(". "S" . $arg1 . $arg2 . ")";
print CHILD "\"$sprm\n";
Lots of other output logic here....
close CHILD;
next;
}
else
{
die "cannot fork: $!" unless defined $pid;
exec "xgraph $plotargs";
exit;
}
Basically, I want xgraph to have a life of its own after the data is
received and plotted.
Any clues?
Thanks in advance,
Kim Helliwell
LSI Logic Corporation
Work: 408 433 8475
Cell: 408 832 5365
kim.helliwell@lsi.com
Please Note: My email address will change to kim.helliwell@lsi.com
<mailto:kim.helliwell@lsi.com> on Oct 14. The old 'lsil.com' email
address will stop working after Jan 15, 2007. Please update your address
book and distribution lists accordingly. Thank you.
| |
| Jeff Pang 2006-10-19, 3:59 am |
|
>I'm not even sure the title is the appropriate terminology. What I am
>trying to do is fork a process that receives data from the parent, but,
>once the data is received, the parent can go on and do whatever it wants
>(and likewise the child). How do I arrange for the child process to be
>detached once the data is sent to it?
>
Hello,
I changed your codes like below:
use strict;
for (my $i=0;$i<2;++$i) {
my $pid = open CHILD,"|-";
select CHILD;$|++;select STDOUT;
if ($pid) {
print CHILD "/etc/passwd";
}else {
my $c = <>;
exec "/bin/cat $c";
}
}
__END__
The parent doesn't get blocked when it finished writing to the childs.It is that,when the parent finished the "print CHILD",it should continue for the next loop,while the childs should do the things they wanted.The childs can't block the parent except tha
t they must read lots of datas from parent then it maybe slow the parent's writting action (due to the buffer).
--
Books below translated by me to Chinese.
Practical mod_perl: http://home.earthlink.net/~pangj/mod_perl/
Squid the Definitive Guide: http://home.earthlink.net/~pangj/squid/
| |
| Kim Helliwell 2006-10-19, 6:56 pm |
| -----Original Message-----
From: Jeff Pang [mailto:pangj@earthlink.net]
Sent: Thursday, October 19, 2006 2:10 AM
To: Helliwell, Kim; beginners@perl.org
Subject: Re: Non-blocking child process
Hello,
I changed your codes like below:
use strict;
for (my $i=0;$i<2;++$i) {
my $pid = open CHILD,"|-";
select CHILD;$|++;select STDOUT;
if ($pid) {
print CHILD "/etc/passwd";
}else {
my $c = <>;
exec "/bin/cat $c";
}
}
__END__
The parent doesn't get blocked when it finished writing to the childs.It
is that,when the parent finished the "print CHILD",it should continue
for the next loop,while the childs should do the things they wanted.The
childs can't block the parent except that they must read lots of datas
from parent then it maybe slow the parent's writting action (due to the
buffer).
__END__
Jeff:
Thanks for taking the time to look at this. I don't think this is the
answer I need, however. If I use cat from the child process, the parent
gets control as soon as cat exits, which it does when it reaches
end-of-file. In my case, I'm launching xgraph from the child, which
doesn't exit until the user click the close button. In that case, the
parent blocks until the close button is clicked. I would like the parent
to continue independently of the child.
Kim Helliwell
LSI Logic Corporation
Work: 408 433 8475
Cell: 408 832 5365
kim.helliwell@lsi.com
| |
| Tom Phoenix 2006-10-19, 6:56 pm |
| On 10/19/06, Helliwell, Kim <Kim.Helliwell@lsi.com> wrote:
> I would like the parent to continue independently of the child.
It sounds as if you want to use the double-fork trick. The first fork
produces a child process; this child forks a grandchild process, then
quits. The grandchild process does the work, and the original parent
process doesn't have to wait once the child quits.
On most Unix systems, the grandchild process will be "adopted" by
another process (conventionally init, process id 1) once its true
parent process is finished.
Since you want to have a pipe from the parent to the grandchild, you
should set that up before the double fork. I generally use Perl's pipe
function to make a pair of filehandles; after forking, the parent
closes the read handle and the grandchild closes the write handle (or
vice versa, if you want data flowing the other way). The grandchild
should re-open STDIN to the read handle before the exec, if I'm
correct about what you want; that might look something like this:
open STDIN, "<&READPIPE"
or die "Can't re-open STDIN to READPIPE: $!";
After that, the process started by the exec should inherit that STDIN
stream, reading whatever the parent sends down the write end of the
pipe.
A special caution is that if the reading process doesn't consume the
input quickly enough, the parent process will block when its output
buffer becomes full. If that becomes a problem for your application,
ask again; there are ways to work around that.
Hope this helps!
--Tom Phoenix
Stonehenge Perl Training
| |
| Dr.Ruud 2006-10-19, 6:56 pm |
| Jeff Pang schreef:
> for (my $i=0;$i<2;++$i) {
Alternative:
for my $i (0 .. 1) {
> my $pid = open CHILD,"|-";
One should always check the return value of open().
> select CHILD;$|++;select STDOUT;
Alternative:
select((select(CHILD),$|=1)[0]);
(from perldoc -q flush)
--
Affijn, Ruud
"Gewoon is een tijger."
|
|
|
|
|