Subroutine lock doesn't work for me. Please help

Discussion in 'Perl Misc' started by poohc1234@yahoo.com, Apr 27, 2005.

  1. Guest

    Hi,
    I have copied the code from perlthrtut.html with the following:
    use Thread qw(yield);
    new Thread \&thread_sub, 1;
    new Thread \&thread_sub, 2;
    new Thread \&thread_sub, 3;
    new Thread \&thread_sub, 4;
    sub sync_sub :locked {
    my $CallingThread = shift @_;
    print "In sync_sub for thread $CallingThread\n";
    sleep 3;
    print "Leaving sync_sub for thread $CallingThread\n";
    }
    sub thread_sub {
    my $ThreadID = shift @_;
    print "Thread $ThreadID calling sync_sub\n";
    sync_sub($ThreadID);
    print "$ThreadID is done with sync_sub\n";
    }

    But it doesn't work. The result I get was:
    Thread 1 calling sync_sub
    In sync_sub for thread 1
    Thread 2 calling sync_sub
    In sync_sub for thread 2
    A thread exited while 6 threads were running.
    Thread 3 calling sync_sub
    In sync_sub for thread 3
    Thread 4 calling sync_sub
    In sync_sub for thread 4

    So I changed the code to be called with join:
    for (0..4)
    {
    $Child[$_] = threads->new(\&thread_sub, $_);
    }
    for (0..4)
    {
    $Child[$_]->join;
    }
    and this still doesn't work because all the threads enters the
    subroutine at the same time. I know this because the code exited after
    3 seconds, instead of 5 clients * 3 seconds. Though I don't understand
    why 2 threads that were still executing with the code exits.

    This is the result:
    Thread 0 calling sync_sub
    In sync_sub for thread 0
    Thread 1 calling sync_sub
    In sync_sub for thread 1
    Thread 2 calling sync_sub
    In sync_sub for thread 2
    Thread 3 calling sync_sub
    In sync_sub for thread 3
    Thread 4 calling sync_sub
    In sync_sub for thread 4
    Leaving sync_sub for thread 0
    Leaving sync_sub for thread 1
    Leaving sync_sub for thread 2
    Leaving sync_sub for thread 3
    Leaving sync_sub for thread 4
    A thread exited while 2 threads were running.

    Very confused.
    Thanks,
    jiac
    , Apr 27, 2005
    #1
    1. Advertising

  2. jiac,

    Useing a shared "lock" variable seems to work for me.

    Try this:

    #!/perl/bin/perl.exe

    use threads;
    use Thread qw(yield);
    my $lock : shared;
    new Thread \&thread_sub, 1;
    new Thread \&thread_sub, 2;
    new Thread \&thread_sub, 3;
    new Thread \&thread_sub, 4;

    # Loop through all the threads
    foreach $thr (threads->list) {
    # Don't join the main thread or ourselves
    if ($thr->tid && !threads::equal($thr, threads->self)) {
    $thr->join;
    }
    }
    print "Done!\n";

    sub sync_sub :locked {
    my $CallingThread = shift @_;
    lock($lock);
    print "In sync_sub for thread $CallingThread\n";
    sleep 3;
    print "Leaving sync_sub for thread $CallingThread\n";
    }

    sub thread_sub {
    my $ThreadID = shift @_;
    print "Thread $ThreadID calling sync_sub\n";
    sync_sub($ThreadID);
    print "$ThreadID is done with sync_sub\n";
    }

    C:\pl>ptest.pl
    Thread 1 calling sync_sub
    In sync_sub for thread 1
    Thread 2 calling sync_sub
    Thread 3 calling sync_sub
    Thread 4 calling sync_sub
    Leaving sync_sub for thread 1
    In sync_sub for thread 2
    1 is done with sync_sub
    Leaving sync_sub for thread 2
    2 is done with sync_sub
    In sync_sub for thread 3
    Leaving sync_sub for thread 3
    3 is done with sync_sub
    In sync_sub for thread 4
    Leaving sync_sub for thread 4
    4 is done with sync_sub
    Done!
    A thread exited while 2 threads were running.


    Kevin Sproule

    <> wrote in message
    news:...
    > Hi,
    > I have copied the code from perlthrtut.html with the following:
    > use Thread qw(yield);
    > new Thread \&thread_sub, 1;
    > new Thread \&thread_sub, 2;
    > new Thread \&thread_sub, 3;
    > new Thread \&thread_sub, 4;
    > sub sync_sub :locked {
    > my $CallingThread = shift @_;
    > print "In sync_sub for thread $CallingThread\n";
    > sleep 3;
    > print "Leaving sync_sub for thread $CallingThread\n";
    > }
    > sub thread_sub {
    > my $ThreadID = shift @_;
    > print "Thread $ThreadID calling sync_sub\n";
    > sync_sub($ThreadID);
    > print "$ThreadID is done with sync_sub\n";
    > }
    >
    > But it doesn't work. The result I get was:
    > Thread 1 calling sync_sub
    > In sync_sub for thread 1
    > Thread 2 calling sync_sub
    > In sync_sub for thread 2
    > A thread exited while 6 threads were running.
    > Thread 3 calling sync_sub
    > In sync_sub for thread 3
    > Thread 4 calling sync_sub
    > In sync_sub for thread 4
    >
    > So I changed the code to be called with join:
    > for (0..4)
    > {
    > $Child[$_] = threads->new(\&thread_sub, $_);
    > }
    > for (0..4)
    > {
    > $Child[$_]->join;
    > }
    > and this still doesn't work because all the threads enters the
    > subroutine at the same time. I know this because the code exited after
    > 3 seconds, instead of 5 clients * 3 seconds. Though I don't understand
    > why 2 threads that were still executing with the code exits.
    >
    > This is the result:
    > Thread 0 calling sync_sub
    > In sync_sub for thread 0
    > Thread 1 calling sync_sub
    > In sync_sub for thread 1
    > Thread 2 calling sync_sub
    > In sync_sub for thread 2
    > Thread 3 calling sync_sub
    > In sync_sub for thread 3
    > Thread 4 calling sync_sub
    > In sync_sub for thread 4
    > Leaving sync_sub for thread 0
    > Leaving sync_sub for thread 1
    > Leaving sync_sub for thread 2
    > Leaving sync_sub for thread 3
    > Leaving sync_sub for thread 4
    > A thread exited while 2 threads were running.
    >
    > Very confused.
    > Thanks,
    > jiac
    >
    Kevin Sproule, Apr 28, 2005
    #2
    1. Advertising

  3. Guest

    Hi Kevin Sproule,
    Thanks for replying, and yes, adding the variable does help. Can I ask
    you a few more questions or whoever:

    1. Why the need to add the $lock variable since doesn't the subroutine
    already have a lock attribute? (and since section on subroutine lock
    didn't mention it.)

    2. The output is " A thread exited while 2 threads were running.".
    What other 2 threads are there?

    3. I didn't understand your comment about "Don't join the main thread
    or ourselves ". I understand the main thread part, but aren't we
    suppose to join ourselves once the exeuction is done?

    Thank you. I am still learning about threads.
    jiac.
    , Apr 28, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fuzzyman
    Replies:
    3
    Views:
    489
    Andrew MacIntyre
    Dec 5, 2003
  2. Robert Brewer
    Replies:
    0
    Views:
    488
    Robert Brewer
    Dec 5, 2003
  3. k3xji
    Replies:
    7
    Views:
    811
    Gabriel Genellina
    Dec 30, 2008
  4. Michael Schmitt

    [threads] problem with subroutine lock

    Michael Schmitt, Dec 20, 2004, in forum: Perl Misc
    Replies:
    0
    Views:
    85
    Michael Schmitt
    Dec 20, 2004
  5. king
    Replies:
    5
    Views:
    184
Loading...

Share This Page