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:

  1. Don't set the itimer to such a low value. This might be the only acceptible way, though I hope not.
  2. Synchronize the threads so they all start their itimers at closer to the same exact time. This might not be feasible -- they're already starting pretty close to the same time. It might be difficult to correct the 1/100th of a second skew. Even if it's possible, I don't have any good ideas how.
  3. Threads are stupid. So are signals. Stop bothering us.
  4. ...?

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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.