Penguin
Annotated edit history of SIGCHLD version 4, including all changes. View license author blame.
Rev Author # Line
1 JohnMcPherson 1 !!!Signal: Child process
2
3 JohnMcPherson 3 Child process has changed state. This signal is raised whenever a child process receives a signal or terminates. This can be used to call wait4(2) to cleanup any ZombieProcess''''es that the process may have. On some Unixes it is possible to explicitly set SIGCHLD to "SIG_IGN" (ignore) and child processes will be cleaned up automatically. The default action (SIG_DFL) for this signal is to ignore it (but this does not reap the process until the parent wait()s).
4
5 From the signal(2) manpage::
6 According to POSIX (B.3.3.1.3) you must not set the action for SIGCHLD to SIG_IGN. Here the BSD and SYSV behaviours differ, causing BSD software that sets the action for SIGCHLD to SIG_IGN to fail on Linux.
7
8 From the sigaction(2) manpage::
9 POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN.
10 POSIX.1-2001 allows this possibility, so that ignoring SIGCHLD can be
11 used to prevent the creation of zombies (see wait(2)). Nevertheless,
12 the historical BSD and System V behaviours for ignoring SIGCHLD differ,
13 so that the only completely portable method of ensuring that terminated
14 children do not become zombies is to catch the SIGCHLD signal and perform a wait(2) or similar.
1 JohnMcPherson 15
2 JohnMcPherson 16
17 In perl, you would do one of the following:
1 JohnMcPherson 18
19 1. wait till child finishes
20
21 ----
3 JohnMcPherson 22 <verbatim>
1 JohnMcPherson 23 if (fork()==0) {
24 # ==0 implies child process
25 do stuff...
26 exit;
27 }
28
29 # if fork returned -1, there was an error forking (but we'll ignore that)
30 # if here, assume it is the parent processes
2 JohnMcPherson 31 # wait() call won't return until the child process has finished.
1 JohnMcPherson 32 wait(); # when this returns, the child has been "reaped"
2 JohnMcPherson 33 # could use waitpid() with WNOHANG to return -1 if child isn't finished yet
1 JohnMcPherson 34 # when here, the child process has finished.
35 ...
3 JohnMcPherson 36 </verbatim>
1 JohnMcPherson 37 ----
38
39 2. Don't care about the child process finishing
40
41 ----
3 JohnMcPherson 42 <verbatim>
1 JohnMcPherson 43 $SIG{CHLD}='IGNORE'; # see the perlipc(1) man page for this...
44
45 if (fork()==0) {
46 do child stuff...
47 exit;
48 }
49
50 continue in parent....
3 JohnMcPherson 51 </verbatim>
1 JohnMcPherson 52 ----
53 If you don't do either of wait() or set the signal handler, then the child will remain a ZombieProcess.
4 KenHylton 54
55 --------------------------------------------------------
56 Interesting note for RedHat enterprise Linux 4 and Fedora 4 users, found with both gcc 3.4.4 (RHEL4) and gcc 4.0.0 (Fedora4): another issue found when ignoring SIGCHLD is that the system() function will not work in your child code. If you ignore SIGCHLD, all of your calls to system() will return -1, indicating that they fail, even though they are actually completed OK. Using this test code:
57
58 <verbatim>
59 pid_t nPid;
60 signal( SIGCHLD, SIG_IGN );
61 if( 0 == ( nPid = fork() ) )
62 {
63 ofstream ofstrTestFile;
64 ofstrTestFile.open( "TestFile.txt", ofstream::out | ofstream::trunc );
65 ofstrTestFile << "Testing...1...2...3...4..." << ends;
66 ofstrTestFile.close();
67 string strTemp;
68 strTemp = "mv TestFile.txt TestFile.mv";
69 int nTemp;
70 nTemp = system( strTemp.c_str() );
71 if ( 0 != nTemp )
72 {
73 cout << "It failed nTemp <" << nTemp << ">" << endl << endl;
74 }
75 else
76 {
77 cout << "It worked nTemp <" << nTemp << ">" << endl << endl;
78 }
79 return ( true );
80 }
81 </verbatim>
82
83 It will fail and return -1. If you remove signal( SIGCHLD, SIG_IGN ); the code will work properly. In either case, the mv command is actually performed successfully.
84
85 This used to work with the signal call in older versions of Redhat and older compilers.

PHP Warning

lib/blame.php:177: Warning: Invalid argument supplied for foreach()