Lately I have been playing with threads and Time::HiRes::setitimer. I find it's a pretty neat way to have many threads do something roughly simultaneously. It works quite well, and I haven't had any major problems -- until I started using low values for the interval. I'm trying to have a bunch of worker threads update their state every 0.1 seconds.
So I wrote a little script to play around with threads and timers:
#!/usr/bin/perl use strict; use warnings; use threads; use Time::HiRes qw(setitimer time ITIMER_REAL); my $NUM = 5; # install main signal handler before creating threads $SIG{ALRM} = sub { local $|=1; print time, ": Caught SIGALRM in main\n +" }; setitimer(ITIMER_REAL, 0.1, 0.1); # create all the threads my $tstart = time; threads->create("run_thread", $_) for (1 .. $NUM); my $tdone = time; printf "%d threads in %f seconds == %d threads/second\n\n", $NUM, $tdone - $tstart, $NUM / ($tdone - $tstart); sleep 1 while 1; sub run_thread { my $num = shift; $SIG{ALRM} = sub { local $| = 1; print time, ": Caught SIGALRM in thread $num\n"; print "\n" if $num == $NUM; }; setitimer(ITIMER_REAL, 0.1, 0.1); sleep 1 while 1; }
With $NUM set to 5, things seem to work as expected. Here's some sample output:
5 threads in 0.079028 seconds == 63 threads/second 1062803574.97634: Caught SIGALRM in main 1062803574.99621: Caught SIGALRM in thread 1 1062803575.02622: Caught SIGALRM in thread 2 1062803575.02631: Caught SIGALRM in thread 3 1062803575.04619: Caught SIGALRM in thread 4 1062803575.05619: Caught SIGALRM in thread 5 1062803575.07617: Caught SIGALRM in main 1062803575.09617: Caught SIGALRM in thread 1 1062803575.12616: Caught SIGALRM in thread 2 1062803575.12621: Caught SIGALRM in thread 3 1062803575.14616: Caught SIGALRM in thread 4 1062803575.15617: Caught SIGALRM in thread 5
First, notice that my system is creating about 63 threads per second (this number is actually fairly stable, surprisingly). That's about 6 threads in 1/10th of a second. Now, notice how close the time values are for thread 5 in the 1st group and main in the 2nd group.
Where I'm getting problems is when I try to use more threads than my system can construct in 1/10th of second. If I change $NUM to 7, I get unreliable and unexpected behavior. Sometimes the groups just overlap, as I would expect. Sometimes perl segfaults. Sometimes I get "runaway" threads that don't seem to follow the interval timer at all. I'm not sure what's causing this behavior, and frankly it's out of my league trying to figure it out.
What my question is really about, is what can I do to workaround this? I can think of a few possible solutions:
Hopefully the ever reliable monks will come up with some ideas for me... :)
In reply to threads and low values with Time::HiRes::setitimer by revdiablo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |