in reply to Threads: How to share a FileHandle to Write

If you want to share a filehandle with all threads, there is no need to pass it to each thread individually. Just open it before you spawn your threads and they will inherit a cloned copy of it. Ie. This runs without errors:

#!/opt/coolstack/bin/perl -w use strict; use threads; use threads::shared; use FileHandle; my $nthreads = 64; my $x : shared; # For sync my $fh = FileHandle->new("> out.txt"); my @thrs; for(1..$nthreads){ print "START $_ \n"; my ($thr) = threads->create(\&worker, $_); push @thrs ,$thr; } $_->join for @thrs; print "STOP: " . localtime() . "\n"; $fh->close; print `wc -l out.txt`; exit; #---------------------------------------------------- sub worker{ my $id = shift; my $tmp; for(1..1000){ lock $x; print $fh "bla blalbla bla blal bla bla bla bla\n" ; #NOT SHARED!! +!! } print "$id>LOAD EXIT\n"; }

And produces:

c:\test>junk4 START 1 START 2 1>LOAD EXIT START 3 2>LOAD EXIT START 4 3>LOAD EXIT ... START 60 59>LOAD EXIT START 61 60>LOAD EXIT START 62 61>LOAD EXIT START 63 62>LOAD EXIT START 64 63>LOAD EXIT 64>LOAD EXIT STOP: Tue May 19 11:37:09 2009 64000 out.txt

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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Threads: How to share a FileHandle to Write
by gulden (Monk) on May 19, 2009 at 10:56 UTC
    The output result is wrong... Each FileHandle in each thread have its own context, we can't print to it concurrently.
    -bash-3.00$ perl threads_file.pl START 1 START 2 1>LOAD EXIT START 3 START 4 START 5 START 6 2>LOAD EXIT 3>LOAD EXIT ... 59>LOAD EXIT START 61 60>LOAD EXIT START 62 61>LOAD EXIT START 63 62>LOAD EXIT START 64 63>LOAD EXIT 64>LOAD EXIT STOP: Tue May 19 11:51:32 2009
    63778 out.txt

      It looks like your C-runtime libraries or Perl implementation is broken(1).

      I cannot reproduce your results on my platform:

      The only logical thing for CLONE to do for an open filehandle is dup() or dup2(), and according to the man pages for those calls:

      NAME dup, dup2 - duplicate a file descriptor SYNOPSIS #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); DESCRIPTION dup and dup2 create a copy of the file descriptor oldfd. After successful return of dup or dup2, the old and new descrip +tors may be used interchangeably.
      They share locks, file position pointers and flags; for example, if the file position is modified by using lseek on one of the descriptors, the position is also changed for the other.
      The two descriptors do not share the close-on-exec flag, howeve +r.

      1. That is, your platform is exhibiting unspecified--thought clearly defined--behaviour.


      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.
        I've tested in more than one SO, and the problem is the same. Try to increase the number of threads, in order to increase concurrency and you will get the same result.