http://www.perlmonks.org?node_id=1029872

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

Hey there monks,

I'm working on a unix environment and perl version 5.16.3

I wanted to create a basic program using threads, so I could understand the basics of it. But, I facing some problems.

I have a variable named "$test". I want to print this variable every time it is increased by one in the while loop

I'm using the following code:

use threads; use threads::shared; my $test :shared; $test = 0; testing_thread(); sub testing_thread { my $thr1 = threads->create(\&progress_count, $test); while ($test <= 100) { $test += 1; } $thr1->join(); } sub progress_count { print $test, " \n"; }

When I excute the script, it only prints the variable $test for one time and that is when it is "101"

Anybody some thoughts on how to print every value of the variable $test? Help is much appreciated!

Many thanks in advance

Replies are listed 'Best First'.
Re: Threading in a loop
by choroba (Cardinal) on Apr 22, 2013 at 13:47 UTC
    If you want the thread to print the value more times, you have to include a loop in the thread. As written, the thread is started, it prints the value and ends.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Yes, does the trick. So basicly, you have to restart the thread every time?

      Thanks!

        Your program finishes too fast. Try this:

        use threads; use threads::shared; my $test :shared; $test = 0; testing_thread(); sub testing_thread { my $thr1 = threads->create(\&progress_count, $test); while ($test <= 1000000) { $test += 1; } $thr1->join(); } sub progress_count { while( $test < 1000000 ) { print $test, " \n"; } }
        I think a better way to put it is that you are going to create or spawn a new thread (not restart the thread).

        You would have to think some more about how to print every time the shared variable changes value.

Re: Threading in a loop
by andal (Hermit) on Apr 23, 2013 at 07:14 UTC

    As already said, your thread prints the value only once, and that can be any value, depending on when the thread got chance to work. If you want your thread to print value every time when it changes, then you have to establish some coordination between your main thread and started thread. In this particular case you may use 2 Thread::Queue objects. Your main thread will push something in the first queue when it incremented the value and wait on the second queue for the moment when the started thread has printed the value. The started thread will wait on the first queue for the moment when the variable was incremented, print the value and then push something into second queue to indicate that printing is finished.

    As you may already see, threads don't make any sense for such simple situation. They just make things complex. In general, try to avoid using threads. They make sense only if they don't modify the same data, at least they do it infrequently. In the best case, a thread would just produce some result and nothing else. Any time there's some shared data, you have a headache of synchronizing access to this data, you have to use locks, semaphores, queues, whatever. And you have to worry about dead-locking and race conditions.

    Don't take me wrong. Threads do have benefits, but they come at cost, and in certain situations the cost becomes too high :)

Re: Threading in a loop
by TomDLux (Vicar) on Apr 24, 2013 at 19:35 UTC

    Your concept is to have two threads, one of which modifies the variable, and the other immediately prints out the new value. Unfortunately, multi-threaded programs don't work like that. Without any communication between the threads, one thread will modify the variable 0 or more times, then the other will print the variable o or more times, and back and forth. There are no guarantees.

    If you want to display what is happening with a variable, you should 'tie' it to a class, as described in http://perldoc.perl.org/functions/tie.html. I believe you would only need to implement a STORE() routine, which would print out the current value of the variable. That way, modifying the variable would cause the value to be displayed.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.