http://qs1969.pair.com?node_id=381204


in reply to Unexpected output from fork (Win32)

$| only affects the output. That means input is still buffered. So when the first thread executes the my $cname= <IN> it reads not only the firs line but the first 4KB and next time it reads the line from its cache, not from the disk. It seems that in your case you were lucky and the 4KB chunks ended at the newlines but I don't think you should not take that for granted. If I try your script on a file generated by

open OUT, '>', 'forklist.txt'; print "computer$_\n" for (1..10000); close OUT;
I do get results like:
...
r1835,checked by -2196
computer1836,checked by -2196
computer1837,checked by -2196
...
computer1965,checked by -2196
computer1966,checked by -2196
computer196ter1250,checked by -4140
computer1251,checked by -4140
computer1252,checked by -4140
...
computer1673,checked by -3928
computer1674,cheputer2713,checked by -3496
computer2714,checked by -3496
...
computer2843,checked by -3496
computer2844,checked by -3496
computeomputer2128,checked by -3120
computer2129,checked by -3120
computer2130,checked by -3120
...

Actually the way you use the $| it only affects STDOUT! Even the OUT handle is buffered! You'd better

use FileHandle; ... OUT->autoflush();
That way you know what handle is unbuffered, $| looks like it is something global which it's not. It affects only the currently select()ed output handle!

You need to change your code to

  1. read the input file only in one thread
  2. flock the output filehandle before writing to it (and set the autoflush correctly)

You may either read the first $no_of_chunks/$no_of_threads into an array, spawn the first child, empty the array in parent, read the next chunk, ... or read the file by the main thread and send the server names to the threads via pipes or Thread::Queue or shared variables or ...

Update (2 minutes after submit) : BrowserUk was quicker :-)

Jenda
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
   -- Rick Osborne