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

I'm wondering if my subroutine "mytest" will be called concurrently and not sequentially? I'm using perl 5.10. Here is the relevant code snippet from the program:
use threads; # concurrently move all the files to the directory passed in on the co +mmand line my $j = 0; for (1..10) { $j++; threads->create(\&mytest); } #Subroutine that does the file copies. This is called concurrently. sub mytest { my $result = `mv ./a_file$j /home/user/dir 2>&1`; }

Replies are listed 'Best First'.
Re: Did I create a concurrent program?
by BrowserUk (Patriarch) on Nov 19, 2008 at 14:29 UTC

    Yes. 10 copies of your sub will run concurrently. And each will see it's own unique value of the closure $j.

    As posted though, the process will die as soon as the last thread is started, with the infamous:

    Perl exited with active threads: 10 running and unjoined 0 finished and unjoined 0 running and detached

    warning, as you are not waiting for them to finish. However, the spawned mv processes will (probably, I've not used iThreads on *nix), continue running to completion.

    In effect, you have coded the equivalent of:

    no threads; my $j = 0; for (1..10) { $j++; `mv ./a_file$j /home/user/dir 2>&1 &`; }

    Whether you will gain any throughput from using concurrency will depend upon your system, no of processors, disks, etc. but as Corion pointed out, any gains will likely be quite small.


    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.
Re: Did I create a concurrent program?
by Corion (Patriarch) on Nov 19, 2008 at 13:56 UTC

    Your mytest routine will run concurrently, but you have a race condition. You should pass the value of $j into the thread at thread creation time instead of accessing a global variable. As your threads run, there is a chance that two threads will try to use the same value in $j to move a file. Also, there is little sense in using threads for IO operations, as IO operations that use the full bandwidth of the bus available seldom benefit from parallelization.

      Your mytest routine will run concurrently, but you have a race condition. You should pass the value of $j into the thread at thread creation time instead of accessing a global variable. As your threads run, there is a chance that two threads will try to use the same value in $j to move a file.
      Aren't Perl variables supposed to be non-shared by default?
      Thanks, I didn't consider that. Thanks for all the advice everyone. I had a problem doing something like this:
      threads->create(\&mytest($j));
      ...and then reading in $j via @_ in the subroutine. This may have something to do with passing by reference via \&? Sorry, I forget what the error was but it wasn't allowed. Any ideas why?