perlipc有以下示例代码:
use POSIX ":sys_wait_h"; # for nonblocking readmy %children;$SIG{CHLD} = sub { # don't change $! and $? outsIDe handler local ($!,$?); my $pID = waitpID(-1,WNOHANG); return if $pID == -1; return unless defined $children{$pID}; delete $children{$pID}; cleanup_child($pID,$?);};while (1) { my $pID = fork(); dIE "cannot fork" unless defined $pID; if ($pID == 0) { # ... exit 0; } else { $children{$pID}=1; # ... system($command); # ... }}
因此,从while循环和处理程序访问%children.这似乎没有问题,因为:
>不会有两个进程具有相同的pID
>访问是由pID键入的(我不确定$childer {pID} = 1是否是原子的,可以中断而不会导致损坏.)
现在,我正在尝试在我的处理程序中做更多事情:
my %categoryForPID;my %childrenPercategory;$SIG{CHLD} = sub { # ... acquire pID like above my $category = $categoryForPID{$pID}; $childrenPercategory{$category}--; delete $categoryForPID{$pID};}while (1) { # ... same as above } else { $children{$pID}=1; my $category = # ... chose some how $childrenPercategory{$category}++; $categoryForPID{$pID} = $category; # ... }}
这里的想法是:每个孩子属于某个类别(N到1).我想跟踪每个类别中有多少个孩子.该信息可以从$categoryForPID派生,但我认为这也可能有问题(例如,当执行计算的子程序在求和时被中断时).
所以我的问题是:
>我需要以某种方式同步吗?
并在旁注:
> perl 5.12中是否可以嵌套调用信号处理程序,还是由解释器线性化?
更新
除了@goldilocks发现的问题和他提出的解决方案之外,我现在在更新数据结构时阻止信号以确保“原子性”:
my $sigset = POSIX::SigSet->new(SIGCHLD);sub ublk { unless (defined sigprocmask(SIG_UNBLOCK,$sigset)) { dIE "Could not unblock SIGCHLD\n"; }}sub blk { unless (defined sigprocmask(SIG_BLOCK,$sigset)) { dIE "Could not block SIGCHLD\n"; }}while (1) { # ... same as above } else { blk; $children{$pID}=1; my $category = # ... chose some how $childrenPercategory{$category}++; $categoryForPID{$pID} = $category; ublk; # ... }}解决方法 对我来说似乎是一个坏主意. IPC :: Semaphore可能会解决这个问题,如果你能让它们在信号处理程序中正常工作 – 如果控制器在处理程序退出之前没有返回,那你就不走运了.但是,您可以通过锁定父级并让子级等待锁定直到初始化完成来解决这个问题.处理程序不涉及信号量.我认为你实际上只需要一把锁.无论如何:
my @array = (1..10);my $x = 'x';$SIG{'USR1'} = sub { print "SIGUSER1\n"; undef @array; $x = '!!';};print "$$\n";foreach (@array) { print "$_:\n"; sleep(2); print "\t$x\n"; print "\t$array[$_ - 1]\n";}
毫不奇怪,这样做:
24821: x 12: x 23:SIGUSER1 !!Use of uninitialized value within @array in concatenation (.) or string at ./test.pl line 42.
暗示如果您在此时捕获信号:
my $category = # ... chose some how
$categoryForPID {$pID}在处理程序中将不存在.等等,是的,你必须同步.
总结以上是内存溢出为你收集整理的perl – 安全地从信号处理程序访问共享数据结构全部内容,希望文章能够帮你解决perl – 安全地从信号处理程序访问共享数据结构所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)