各种$ SIG {CHLD}值之间有什么区别? [英] What's the difference between various $SIG{CHLD} values?

查看:228
本文介绍了各种$ SIG {CHLD}值之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些设置之间有什么区别?

What is the difference between these settings?

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

根据"UNIX环境中的高级编程,第二版",图10.1,SIGCHLD的默认值为忽略".

According to "Advanced Programming in the UNIX Environment, 2nd edition", figure 10.1 the default value of SIGCHLD is "ignore."

如果忽略"的意思是"SIG_IGN",那么没有孩子会成为僵尸,事实并非如此.

If "ignore" meant "SIG_IGN", then no child would ever be a zombie, and that's not the case.

从那里还不清楚:

如果进程专门将其处置方式设置为SIG_IGN,则子进程 的调用进程不会生成僵尸进程.注意 这不同于它的默认操作(SIG_DFL),如图 10.1将被忽略.相反,在终止时,这些子进程的状态 被丢弃.

If the process specifically sets its disposition to SIG_IGN, children of the calling process will not generate zombie processes. Note that this is different from its default action (SIG_DFL), which from Figure 10.1 is to be ignored. Instead, on termination, the status of these child processes is discarded.

我很难理解各种值(或未定义的非值)的影响.到目前为止,解决方案一直是轮流浏览这些选择,直到获得所需的行为为止,而我宁愿确切地了解每个值如何定义信号的行为.

I'm having a hard time groking what the impact of the various values (or undefined non-value) are. So far, the solution has been to rotate through those choices until I get the desired behavior, and I'd rather understand exactly how each value defines the behavior of the signal.

行为:子进程正在调用系统"或使用反引号来创建另一个子进程,并且该信号通常会被错误的(父)处理程序捕获.设置本地处理程序可以工作,但是如果我希望孙子的信号不执行任何操作,我不知道哪个值最合适.

The behavior: a child process is calling "system" or using backticks which create another child, and the signal would normally be caught by the wrong (parent) handler. Setting a local handler can work, but I don't understand which value is most appropriate if I want the signal from the grand-child to do nothing.

有人可以照亮我吗?

更新: 根据池上的反馈,我进行了一些具体的测试.该行为至少部分是平台特定的.

UPDATE: Based on ikegami's feedback, I did some specific testing. The behavior is, at least partially, platform specific.

考虑以下片段:

$SIG{CHLD} = sub {
    while( ( my $child = waitpid( -1, &WNOHANG ) ) > 0 ) {
        print "SIGNAL CHLD $child\n";
    }
};

my $pid = fork();

if( ! $pid ) {
    system( 'echo Grandchild PID = $$' );
    sleep 2;
    exit;
}

print "Child PID = $pid\n";
sleep 5;

Solaris 10上的Perl 5.8.6将显示system()调用的PID的"SIGNAL CHLD"消息.做任何事情,甚至像

Perl 5.8.6 on Solaris 10 will display "SIGNAL CHLD" messages for the PID of the system() call. Doing anything, even as trivial as

本地$ SIG {CHLD};

local $SIG{CHLD};

在孩子中的

会禁止显示这些消息.

in the child will suppress those messages.

在我尝试过的所有其他口味上,收割者再也见不到孩子了.

On every other flavor I tried, the reaper never sees the child.

推荐答案

请参见 %SIG .

$SIG{CHLD} = 'IGNORE';使您的进程忽略SIGCHLD信号.

$SIG{CHLD} = 'IGNORE'; causes your process to ignore SIGCHLD signals.

$SIG{CHLD} = 'DEFAULT';会使您的进程对待SIGCHLD信号,就像您不会弄乱$SIG{CHLD}或同等的信号一样.根据kill(1)的说法,我系统上的进程默认情况下会忽略SIGCHLD

$SIG{CHLD} = 'DEFAULT'; causes your process to treat SIGCHLD signals as it would had you not messed with $SIG{CHLD} or equivalent. According to kill(1), a process on my system ignores SIGCHLD by default

$SIG{CHLD} = '';$SIG{CHLD} = undef;是无效值.

关于收割,其SIGCHLD处理程序显式设置为IGNORE的父母的孩子将在退出时由系统自动收割.

As for reaping, children of a parent whose SIGCHLD handler is explicitely set to IGNORE will be reaped automatically by the system as soon as it exits.

$ perl -e'
   my $pid = fork;
   if (!$pid) { sleep(1); exit; }
   sleep(2);
   system "ps -o pid,stat,command $pid";
'
  PID STAT COMMAND
14667 ZN+  [perl] <defunct>

$ perl -e'
   $SIG{CHLD}="IGNORE";
   my $pid = fork;
   if (!$pid) { sleep(1); exit; }
   sleep(2);
   system "ps -o pid,stat,command $pid";
'
  PID STAT COMMAND

$

这篇关于各种$ SIG {CHLD}值之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆