Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re^11: [threads] Open a file in one thread and allow others to write to it

by ikegami (Pope)
on Nov 16, 2009 at 17:45 UTC ( #807525=note: print w/replies, xml ) Need Help??

in reply to Re^10: [threads] Open a file in one thread and allow others to write to it
in thread [threads] Open a file in one thread and allow others to write to it

There's no race condition there. Notice the timestamps aren't in order? You never ask Perl to write to disk, so it writes in 4k chunks, whether the chunk ends in the middle of a line or not.

Simplest solution: Change

open LOG, '>', 'log.txt' or die $!;
use IO::Handle qw( ); open LOG, '>', 'log.txt' or die $!; LOG->autoflush(1);

If you're still having jumbled output after fixing the above problem, there might be a problem keeping file pointers in sync. Use the following before the print:

use Fcntl qw( :seek ); seek(LOG, 0, SEEK_END);

I don't think it'll come to that, though.

Replies are listed 'Best First'.
Re^12: [threads] Open a file in one thread and allow others to write to it
by gulden (Monk) on Nov 16, 2009 at 19:49 UTC

    The AUTOFLUSH does not solve the problem

    The SEEK works !!! and it works without the lock in $sem and the AUTOFLUSH in LOG. However, IMHO the lock in $sem must be used

    In overall i've understand your tip, but it's not clear for me how all the file pointers are syncked in a thread concurrency level, without conflicts. With the lock in $sem it's obvious , because only one thread can SEEK the Filehandle and write to it. However, I'm getting the log file syncked without using the lock in $sem. But these are other discussions

    Thanks for the tip it will be very useful for me...

      and it works without the AUTOFLUSH in LOG.

      seek apparently forces a flush. Assuming it's safe to rely on that, it's not good enough. The catch is that it's forcing the flush at the wrong time. You want to flush immediately after the print, not at the start of the thread's next print.

      and it works without the lock in $sem

      You're relying on your OS to do writes atomically. That might be reliable for small writes, but why chance it. If you do find a performance bottleneck, you might be better off using a separate log file for each thread and merge them later.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://807525]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2018-06-19 05:31 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (111 votes). Check out past polls.