What's the difference between various $SIG{CHLD} values?

后端 未结 4 1100
悲&欢浪女
悲&欢浪女 2020-12-16 22:22

What is the difference between these settings?

$SIG{CHLD} = \'IGNORE\'  
$SIG{CHLD} = \'DEFAULT\'  
$SIG{CHLD} = \'\'  
$SIG{CHLD} = undef

4条回答
  •  暖寄归人
    2020-12-16 22:58

    There are two ways to avoid creating zombie processes:

    1. explicitly set $SIG{CHLD}='IGNORE'
    2. reap the dead children explictly with the wait or waitpid calls (this could be done inside a SIGCHLD handler, but it need not be)

    Setting $SIG{CHLD}='IGNORE' traps the SIGCHLD at the operating system level, cleaning up the child process without even signalling your Perl program.

    Any other setting, including 'DEFAULT', undef, "", sub {}, 'some_function_name_that_doesnt_even_exist' will cause the signal to be delivered to Perl, and the child will not be reaped automatically.

    By reaping the process yourself with wait and waitpid, you can get additional information like the exit status of the child process, and (more-or-less) the order in which the child processes finished. If $SIG{CHLD} is set to 'IGNORE', wait and waitpid always return -1 and don't set $?.

    The SIGCHLD, if any, is always delivered to the process that spawned the child process, so I don't think you are correct to say that a SIGCHLD from a grandchild process (from a system call in a child process) is caught in the parent process. Probably what is going on is that your child process inherits the signal handler from its parent process.

    system and backticks will (on most systems) generate a SIGCHLD on completion and will set the $? value with the command's exit status. But Perl will reap these subprocesses itself, and you won't be able to capture the process id of a system or backticks call with wait or waitpid.

提交回复
热议问题