Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix

by ait (Hermit)
on May 10, 2009 at 15:33 UTC ( #763139=perlquestion: print w/replies, xml ) Need Help??

ait has asked for the wisdom of the Perl Monks concerning the following question:

Hello, fellow monks.

I am aware that the 5.8 threads model differs from system to system and compiling options so after reading the POD over and over, super-searching PM and reading up on several thread-threads, and actual code testing, I am still left with some doubt, and would greatly appreciate any experts here for their $0.02!

First, I assume that the Linux, FreeBSD and most other Unix or Unix-like systems, except perhaps for Solaris, must have very similar threads implementations with the vanilla Perl 5.8.x offered in these platforms. I would assume that for example in most Linux systems, a vanilla Perl threads implementation will use, or compiled by default to use LWP aka Kernel Threads. Any in-depth comments for *nix OSs here very welcome.

Second, and my actual question is that if using threads->yield _plus_ a millisecond delay with Time::HiRes is redundant, and if the snippet below is doing what I want: to yield at least 250 milliseconds of time to other threads before checking for the queue again. I am thinking that the yield is actually issuing a single no-op and really isn't doing much... but is the usleep() accomplishing what I need?

Thridly, I would like to know if using Time::HiRes is thread safe, especially if I'm using Perl GTK2 which make everything a lot more fragile (not because of Perl but because of GTK-intrinsic threading flaws, which I have already learned to tame for the most part).

REPEAT: [...] # gomr note ready yet... if($imgaq->pending){ # yield CPU... threads->yield; # 250 milisecond delay usleep(250000); warn "GOMR NOT READY..."; goto REPEAT; }

Thanks a bunch in advance,
Alejandro Imass
  • Comment on Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
  • Download Code

Replies are listed 'Best First'.
Re: Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
by ikegami (Pope) on May 10, 2009 at 18:31 UTC

    I concur. Sleeping already relinquishes the CPU, so yield is redundant and wasteful.

    At least that's the theory, but it's supported by the following program using 0% CPU:

    use Time::HiRes qw( usleep ); for (;;) { usleep(250000); }

    Do you have any reason to believe otherwise?

    Update: Screw theory, the following shows usleep does what you want.

    use strict; use warnings; use Time::HiRes qw( usleep time ); use threads; { my $i = 0; my $s = time; my $t1 = async { usleep(250000); }; my $t2 = async { ++$i while $i < 50_000_000; }; $_->join() for $t1, $t2; my $e = time; printf("%.0f\n", ($e-$s)*100000); } { my $i = 0; my $s = time; my $t1 = async { }; my $t2 = async { ++$i while $i < 50_000_000; }; $_->join() for $t1, $t2; my $e = time; printf("%.0f\n", ($e-$s)*100000); }
      Update: Screw theory, the following shows usleep does what you want.

      Could you explain what you think that code demonstrates?

      C:\test> 346500 346021 C:\test> 345600 345841 C:\test> 346100 345553

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Looks to me like the usleep thread allows the other thread to execute with little to no hindrance. As far as I understand it, that was the OP's question.
      Wow, Great example! Thanks for taking the time to write it up!
      sleep and yield both take the thread off the cpu. If priorities are involved (which they prolly are not in this) then the thread that yields could get put back on immediatly. the sleeping thread will wait until it is woken up at the end of its time. so both should accomplish the goal giving up the cpu, the sleep just wastes a lot processor time. If only one thread is running then you have to wait all that time with the cpu at 0%. yield should give everyone else a chance then come back ASAP. Well it depends on the schedluer of course, but linux is smart
Re: Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
by JavaFan (Canon) on May 10, 2009 at 16:36 UTC
    If you do a yield you're telling the sceduler that another thread may do its business. Whether another thread will do so depends on whether there's another thread wanting the CPU, and on implementation details of your OSses sceduler. But you are doing the sleep only after the thread gets another timeslice. During the sleep, other threads (or processes) may do their thing.

    I'm not a thread expert, but I think the best thing you can do is leave the sleep in, and remove the yield.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://763139]
Approved by AnomalousMonk
Front-paged by tye
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2020-01-25 05:01 GMT
Find Nodes?
    Voting Booth?