J
Justin Fletcher
Hiya,
I'm having a problem trying to get a simple program to respond the way
that I expect. The basic premise is thus :
1. Fork a child.
2. Sleep for a while.
3. Do other stuff.
This seems pretty simple, and I have a SIGCHLD handler which will catch my
forked process if it exits. I thought everything was fine. Then I found
that is I press ctrl-Z to suspend the parent whilst I'm running the
program and then background it, it hangs. I've reduced the problem to the
simplest I can, as follows :
----
#!/bin/perl
$SIG{'CHLD'} = sub {
print "SIGCHLD\n";
$pid = wait;
print "leave SIGCHLD for pid $pid\n";
};
print "Forking to do some long running task\n";
unless ($pid = fork) {
$SIG{'CHLD'} = 'DEFAULT';
exec "tail -f /dev/null";
die "failed\n";
};
print "Sleeping\n";
sleep 50;
print "Waking\n";
----
The problem is that if I press ctrl-Z whilst the program is sleeping, and
then resume it in the background with 'bg', a SIGCHLD is triggered. The
handler then does a 'wait' to get the PID and hangs because there isn't a
child that's exited. We never leave the SIGCHLD handler (unless the long
running task completes). The use of 'tail -f /dev/null' is purely to
simulate a task which just keeps running.
In the shell, the following sequence is seen:
----
justin@buttercup:~/Root/perltest$ perl testsleep.pl
Forking to do some long running task
Sleeping
[1]+ Stopped perl testsleep.pl
justin@buttercup:~/Root/perltest$ bg
[1]+ perl testsleep.pl &
SIGCHLD
justin@buttercup:~/Root/perltest$
----
I'm running bash 3.1.17, linux kernel 2.6.18, from debian stable, with
perl 5.8.8.
I believe this sort of construct to be normal and even recommended from
the perlipc pages; so... am I doing something wrong ? is bash ? is the
kernel ? is perl ?
I'm hoping I'm just misunderstanding how process control should be done.
I'm having a problem trying to get a simple program to respond the way
that I expect. The basic premise is thus :
1. Fork a child.
2. Sleep for a while.
3. Do other stuff.
This seems pretty simple, and I have a SIGCHLD handler which will catch my
forked process if it exits. I thought everything was fine. Then I found
that is I press ctrl-Z to suspend the parent whilst I'm running the
program and then background it, it hangs. I've reduced the problem to the
simplest I can, as follows :
----
#!/bin/perl
$SIG{'CHLD'} = sub {
print "SIGCHLD\n";
$pid = wait;
print "leave SIGCHLD for pid $pid\n";
};
print "Forking to do some long running task\n";
unless ($pid = fork) {
$SIG{'CHLD'} = 'DEFAULT';
exec "tail -f /dev/null";
die "failed\n";
};
print "Sleeping\n";
sleep 50;
print "Waking\n";
----
The problem is that if I press ctrl-Z whilst the program is sleeping, and
then resume it in the background with 'bg', a SIGCHLD is triggered. The
handler then does a 'wait' to get the PID and hangs because there isn't a
child that's exited. We never leave the SIGCHLD handler (unless the long
running task completes). The use of 'tail -f /dev/null' is purely to
simulate a task which just keeps running.
In the shell, the following sequence is seen:
----
justin@buttercup:~/Root/perltest$ perl testsleep.pl
Forking to do some long running task
Sleeping
[1]+ Stopped perl testsleep.pl
justin@buttercup:~/Root/perltest$ bg
[1]+ perl testsleep.pl &
SIGCHLD
justin@buttercup:~/Root/perltest$
----
I'm running bash 3.1.17, linux kernel 2.6.18, from debian stable, with
perl 5.8.8.
I believe this sort of construct to be normal and even recommended from
the perlipc pages; so... am I doing something wrong ? is bash ? is the
kernel ? is perl ?
I'm hoping I'm just misunderstanding how process control should be done.