0

前段时间我遇到了问题,$SIG{WINCH}因为我加载了两个在模块中使用$SIG{WINCH} $SIG{WINCH} 时都使用问题的模块。现在我试图重建这个案例,但这次我把一个模块$SIG{WINCH}放在一个子程序中。

use warnings;
use strict;
package My_Package;
use Exporter 'import';
our @EXPORT = qw(choose);

sub choose {
    # ...
    my $size_changed;
    local $SIG{WINCH} = sub { $size_changed = 1; }; # edit: added "local"
    while ( 1 ) {
        my $c = getch();
        if ( $size_changed ) {
            write_screen();
            $size_changed = 0;
            next;
        }
        # ...
    }
}

现在看起来它正在工作。如果我$SIG{WINCH}以这种方式进行本地化,我会保存还是在重建时忘记了什么?

4

1 回答 1

1

这是有效的,因为您的代码在设置信号处理程序后立即进入while循环,因此没有其他代码可以运行(或设置新的处理程序)。当 while 循环退出时,您的处理程序未设置,旧的处理程序会自动恢复,这要归功于local.

对于更有弹性的代码,我会检查是否存在现有的信号处理程序,然后调用它。否则任何其他具有 SIGWINCH 处理程序的模块都将被破坏。例如

my $orig_sigwinch = $SIG{WINCH};
local $SIG{WINCH} = sub {
    $orig_sigwinch->() if $orig_sigwinch && ref $orig_sigwinch eq 'CODE';
    $size_changed = 1;
}

请注意,这不考虑$orig_sigwinch函数名称而不是代码引用的情况。

于 2012-08-11T09:45:43.607 回答