perl – 安全地从信号处理程序访问共享数据结构

perl – 安全地从信号处理程序访问共享数据结构,第1张

概述我试图决定从为x86_64- linux-thread-multi构建的perl(v5.14.2)中的信号处理程序访问公共(读取:处理程序代码和程序的其余部分之间的共享)数据结构是否安全,但目标平台是solaris11). perlipc有以下示例代码: use POSIX ":sys_wait_h"; # for nonblocking readmy %children;$SIG{CHLD} 我试图决定从为x86_64- linux-thread-multi构建的perl(v5.14.2)中的信号处理程序访问公共(读取:处理程序代码和程序的其余部分之间的共享)数据结构是否安全,但目标平台是solaris11).

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 – 安全地从信号处理程序访问共享数据结构所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1232997.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存