开发者

Problem with perl signal INT

I have the following perl code on windows activestate perl 5.8

  $SIG{INT}=\&clean;

  ...
  sub clean {

  print 'cleaning...';
  ...
  ...
  exit 0;

  }

but when i try to close开发者_如何学C my program by Ctrl^c it didn't enter the sub clean at all could someone help why did i miss something ?


It seems that Windows doesn't provide signals as in Unix.

From man perlwin32:

Signal handling may not behave as on Unix platforms (where it doesn't exactly "behave", either :). For instance, calling "die()" or "exit()" from signal handlers will cause an exception, since most implementations of "signal()" on Win32 are severely crippled. Thus, signals may work only for simple things like setting a flag variable in the handler. Using signals under this port should currently be considered unsupported.


I'd say no. I can't see anything wrong with what you're doing. I wrote a test program that actually runs:

#!/usr/bin/perl

use strict;
use warnings;

$SIG{INT}=\&clean;

sub clean {
    print 'caught';
}
sleep 10;

Tested on Linux, this works as expected, but I don't have AS perl handy to try it. Try it yourself on your machine.

Also, print to STDERR to ensure it's not something very odd going on with print buffering.


I found that the script given by @ijw (modified to be what it is below) does not work under Active State Perl version v5.10.1:

This is perl, v5.10.1 built for MSWin32-x86-multi-thread
(with 2 registered patches, see perl -V for more detail)

My modification below adds the autoflush calls (as otherwise the sleep below would not show the print statement output at all while sleeping):

#!/usr/bin/perl

use IO;
use strict;
use warnings;

# Set autoflushing on to stdout and stderr.  Otherwise, system() call and stdout output does not show up in proper sequence,
# especially on Windows:
STDOUT->autoflush(1);
STDERR->autoflush(1);

$SIG{INT}=\&clean;

sub clean {
    print "caught\n";
    exit (0);
}

print "before sleep\n";
sleep 100;
print "after sleep and then exiting\n";
exit (0);

When I commented out the following lines in that script above:

$SIG{INT}=\&clean;

sub clean {
    print "caught\n";
    exit (0);
}

And then hitting CTRL-C during the sleep, the script does terminate and show this message:

Terminating on signal SIGINT(2)

Hence it must actually still be true (well, for ActiveState Perl v5.10.1) what man perlwin32 states:

... most implementations of "signal()" on Win32 are severely crippled. ...

For future reference:

  1. perlmonks refers to the use of Win32::API to setup a call to the SetConsoleCtrlHandler Win32 function.
  2. All about SetConsoleCtrlHandler.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜