Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^3: Setting signal handlers

by ruoso (Curate)
on May 09, 2006 at 21:52 UTC ( #548335=note: print w/replies, xml ) Need Help??


in reply to Re^2: Setting signal handlers
in thread Setting signal handlers

Well, back in 2000, I gave up on a module (Server::FastPL, now on backpan) because of lost signals and unix sockets constant lock up... My experience told me to not trust signals for anything really important... I did use the $SIG way... maybe the problem is related...

daniel

Replies are listed 'Best First'.
Re^4: Setting signal handlers
by dave_the_m (Monsignor) on May 09, 2006 at 22:01 UTC
    In perl 5.8.0, released in 2002, we introduced the concept of 'safe signals'. This makes the perl interpreter interruptable onbly on opcode boundaries. This removed a lot of the reentrancy and race problems that perl used to have handling signals, at the risk of sometimes delaying the handling of the signal.

    You may want to see if your old signal code workes better now.

    Dave.

      Hmmm... a crash-test told me it's still not so trustworthy... Still got lost signals and duplicated responses...

      Summary
      PID: LOST SIGNALS
      5023: 3
      5024: 12
      5025: 12
      5026: 3
      5027: 6
      5028: 5
      5029: 6
      5030: 1
      5031: 4
      5032: 8
      parent: 9319
      PID: MAX_TIME, MIN_TIME, COUNT, MED
      5023: 0.0395898818969727, 2.00271606445312e-05, 997, 0.000217293066868452
      5024: 0.0297799110412598, 2.98023223876953e-05, 988, 0.00015578627103736
      5025: 0.0275199413299561, -0.00189995765686035, 988, 0.0001988222724513
      5026: 0.0194199085235596, 2.98023223876953e-05, 997, 0.000203705599219534
      5027: 0.0242300033569336, 2.00271606445312e-05, 994, 0.000233370053696201
      5028: 0.0375699996948242, 2.98023223876953e-05, 995, 0.000291356609095281
      5029: 0.0186100006103516, 2.98023223876953e-05, 994, 0.000193814636476083
      5030: 0.0270700454711914, 2.98023223876953e-05, 999, 0.000180974498286739
      5031: 0.0173900127410889, 1.97887420654297e-05, 996, 0.000126030071672187
      5032: 0.0372300148010254, 2.98023223876953e-05, 992, 0.000203564522727843
      parent: 0.0304899215698242, -0.016819953918457, 10551, 0.000104144584193703
      

      The negative MIN_TIME means that a response was sent before the signal (in a stack)...

      Follows the code to do the crash-test...

      #!/usr/bin/perl use strict; use warnings; use Time::HiRes 'usleep'; my $num_processes = 10; my $signals_per_process = 1000; $| = 1; my @pids; $SIG{USR2} = sub { print "parent received ".Time::HiRes::time().$/ }; FORKS: while ($num_processes > 0) { my $parent = $$; if (my $pid = fork()) { push @pids, $pid; } else { $SIG{USR1} = sub { print $$." received ".Time::HiRes::time().$ +/; }; while (1) { usleep(rand(20)); print "parent signalled ".Time::HiRes::time().$/; kill('USR2',$parent) or exit; } exit; } $num_processes--; } for (1..$signals_per_process) { PROCESS: foreach my $id (@pids) { print $id." signalled ".Time::HiRes::time().$/; kill("USR1", $id); usleep(rand(20)); } } exit;

      And the code to generate the summary:

      #!/usr/bin/perl use warnings; use strict; my %data; my %report; while (<STDIN>) { chomp; my ($pid, $op, $time) = split /\s/; if ($op eq 'signalled') { push @{$data{$pid}}, $time; } else { my $sigtime = pop @{$data{$pid}}; push @{$report{$pid}}, $time - $sigtime; } } print "Summary".$/; print "Lost:".$/; foreach my $pid (sort keys %data) { print $pid.": ".scalar(@{$data{$pid}}).$/; } print "Received: ".$/; foreach my $pid (sort keys %report) { my ($min, $max, $count, $sum); foreach my $time (@{$report{$pid}}) { $min = $time if (not defined $min or $min > $time); $max = $time if (not defined $max or $max < $time); $count++; $sum += $time; } print $pid.": $max, $min, $count, ".$sum/$count.$/; }
      daniel
        Perl will only call a particular signal handler once per signal number - no matter how many times it recieves that signal type *before* handling it.

        But there's a general flaw with your stress code; you have multiple processes all writing to stdout (which I presume is redirected to a file), and that's likely to lose or duplicate output, even with $|=1:

        $ cat /tmp/p1 #!/usr/bin/perl $| = 1; for (1..10) { if (fork == 0) { print "$_\n" for 1..100; exit; } } $ perl588 /tmp/p1 > /tmp/x ; wc -l /tmp/x 900 /tmp/x $ perl588 /tmp/p1 > /tmp/x ; wc -l /tmp/x 983 /tmp/x $ perl588 /tmp/p1 > /tmp/x ; wc -l /tmp/x 1000 /tmp/x
        Either open the file in append mode and only syswrite to it, or have each process write to a separate file.

        Dave.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://548335]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2020-11-29 20:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?