in reply to Re: baton passing threads and cond_signal
in thread baton passing threads and cond_signal

Thanks. That clears up the cond_signal thing, but regarding the caveat and your update.

With the following code, which I think incorporates all your changes,if I leave the sleep in, or as show, replace it by yield, any number of threads appear to run reliably.

But if I comment out the yields, it locks up almost straight away. Do you get a different result?

I'm running this on a single processor. Are you using a multi?

use strict; use warnings; use Time::HiRes 'sleep'; use threads 'yield'; use threads::shared; my $baton:shared = 0; sub sprinter { my ($no_of_threads,$sleep) = @_; my $id = threads->self->tid; warn ("Thread $id started\n"); while (1) { lock ($baton); cond_wait ($baton) until $baton == $id; warn ("Thread $id has the baton\n"); # yield; $baton = int (rand ($no_of_threads)) until $baton != $id; warn ("Thread $id passing the baton to thread $baton\n"); cond_broadcast ($baton); } } my ($no_of_sprinters) = @ARGV; $no_of_sprinters ||= 3; my @threads; push @threads,threads->new (\&sprinter,$no_of_sprinters) for 1..$no_of_sprinters; sleep 1; while(1){ lock ($baton); cond_wait ($baton) until $baton == 0; warn ("Thread 0 has the baton\n"); # yield; $baton = int (rand ($no_of_sprinters))+1 until $baton != 0; warn ("Thread 0 passing the baton to thread $baton\n"); cond_broadcast ($baton); }

Replies are listed 'Best First'.
Re^3: baton passing threads and cond_signal
by Joost (Canon) on Aug 21, 2007 at 21:53 UTC
    As you posted it, the code works fine for me.

    When using threads (as when using unicode or the other fairly recent additions to perl) you should probably run the latest (stable) version of perl and the relevant modules.

    I'm running perl 5.8.8 on debian linux, with threads version 1.62 (a few months old) and threads::shared version 1.12 (that's the current version) - note: the threads modules included in the standard perl 5.8.8 distribution are much older than that.

    update: yes I'm running this on a core-2 duo intel machine (32 bit linux), so that would work like a multi-processor machine.

      I have the same versions of everything, 5.8.8, threads 1.62, threads::shared 1.12, (and I reinstalled everything to be sure) and without the yields or sleep 0, it locks up within a couple of seconds. The differences are I'm on XP, and on a single processor.

      It would be good to know which is the cause. The processor or the platform?

      Thanks for your kind help.

        The problem may be in differences in thread implementation on unix and windows. If, for example, cond_broadcast() "nests" in one implementation and not in the other, you may get cascading broadcasts. i.e.

        Say you've got 10 threads waiting on the same condition like in your code. When you broadcast, you'll wake up all threads one after another. But in the mean time, one of the threads (the one who's thread id matches the baton) will broadcast. So now you're waking up all threads again while you're not done waking up the rest of the threads, and so on. That might grind the program to a halt fairly quickly if the broadcasts do not terminate when a new broadcast is done on the same condition variable.

        Now I'm not sure if that's what happens. If it is, I suspect you'd see the process taking up a lot of CPU time, while if the problem is some kind of deadlock, you'd see the process taking essentially no CPU time at all.