Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^4: Setting signal handlers

by dave_the_m (Monsignor)
on May 09, 2006 at 22:01 UTC ( #548337=note: print w/replies, xml ) Need Help??


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

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.

Replies are listed 'Best First'.
Re^5: Setting signal handlers
by ruoso (Curate) on May 09, 2006 at 23:18 UTC

    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.

        well the output surprises me...at the OS level a child will get a copy of the parent descriptor but __does share__ the file offset, so if they write at the same time, their output will be intermixed. but i really don't see how you can lose any \n on cygwin I cannot reproduce what you get tomorrow at work I will try on HP-UX... 100 runs with 1000 print in each process

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2021-01-21 18:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?