%SIG
のシグナルにサブを割り当てると、Perlはカウンタをインクリメントするシグナルハンドラをインストールします。このカウンタは、Perlオペコードの間でチェックされます。 [1]その時だけ、Perlサブ・コールが呼び出されます。
プリインクリメント、ポストインクリメント、プリデクリメントおよびポストデクリメントはすべてPerlオペコードであるため、信号によって中断されることはありません。
$ perl -MO=Concise,-exec -e'my $x; ++$x; --$x; $x++; $x--;'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> padsv[$x:1,2] vM/LVINTRO
4 <;> nextstate(main 2 -e:1) v:{
5 <0> padsv[$x:1,2] sRM
6 <1> preinc vK/1
7 <;> nextstate(main 2 -e:1) v:{
8 <0> padsv[$x:1,2] sRM
9 <1> predec vK/1
a <;> nextstate(main 2 -e:1) v:{
b <0> padsv[$x:1,2] sRM
c <1> preinc[t2] vK/1
d <;> nextstate(main 2 -e:1) v:{
e <0> padsv[$x:1,2] sRM
f <1> predec[t3] vK/1
g <@> leave[1 ref] vKP/REFC
-e syntax OK
また$p
が、それは安全ですかどうかを決定するためにシグナルハンドラの外で使用されている方法を確認する必要があります。例えば、シグナルハンドラの外側にあるコードが中断する可能性があるため、次のコードを実行すると問題が発生します。
$p = $p - 1;
これは安全です:
my %children;
$SIG{CHLD} = sub {
local ($?, $!, $^E);
while ((my $pid = waitpid(-1, WNOHANG)) > 0) {
my $child = $children{$pid}
or next; # ?!?
$child->{exit_status} = $?;
}
};
while (1) {
...
for my $pid (keys(%children)) {
my $child = $children{$pid};
defined(my $exit_status = $child->{exit_status})
or next;
delete($children{$pid});
...
}
...
}
- 私はそれがPerlのの最近のバージョンでさえ少ない粒状行われていると思います。
「安全」なのかどうかにもよると思います。私は、 'SIGCHLD'ハンドラのハッシュへの代入に基づいてフロー制御を使用する長期実行型(ただし重要ではありませんが)コードを持っています。いくつかのソケット読み取りはシグナルハンドラによって中断されますが(割り当てのためではありません)、ハンドラ自体には問題はなく、予期しないこともありません。しかし、単一のオペコードについてはわかりません。 – zdim
ハッシュの更新が複数のオペコード(アイデアなし)で行われている場合、それを使って作業していて途中で中断した場合、どうなりますか? –
ハッシュにキーと値のペアを追加するのは複雑で、1つのオペコードではないことは間違いありません。 _that_が中断された場合、良いことは起こりません。しかし、私は、変数に準備値を割り当てるだけのハンドラのコードが中断されるという非常に小さなチャンスがあると思います(私はそれがどう起こるのか分かりません)。それがもっとしているなら、それは違う。ご注意:私は必要なだけのことをするのが最善だと思います。 – zdim