in reply to Re: Slow worker threads
in thread Slow worker threads

Let's consider NONBLOCKING flock , there's something really wrong going on :

use strict; use warnings; use threads; use feature 'say' ; use Fcntl qw(:flock); open(FILE, ">>/tmp/test.txt"); for(0..9) { threads->new(\&worker, $_); } $_->join for threads->list; sub worker { my $x = shift; my $locked; $locked = flock(FILE, LOCK_EX|LOCK_NB ); if( $locked ) { say "$x: lock acquired"; sleep 4; } else { say "$x: cannot acquire lock"; } flock( FILE, LOCK_UN ); print "$x: lock released\n"; return; }
0: lock acquired 1: lock acquired 2: lock acquired 3: lock acquired 4: lock acquired 5: lock acquired 6: lock acquired 7: lock acquired 8: lock acquired 9: lock acquired 0: lock released 1: lock released 2: lock released 3: lock released 4: lock released 5: lock released 6: lock released 7: lock released 8: lock released 9: lock released

How come the lock is acquired again and again without being released anywhere in between ?!

Isn't this what a lock is supposed to do ? Lock something and not give access to anyone else until released ?

Replies are listed 'Best First'.
Re^3: Slow worker threads
by spx2 (Deacon) on Jul 18, 2009 at 19:20 UTC

    it didn't occur to me that the threads were actually sharing the FILE filehandle , so if one acquired the lock , each of them actually acquired the lock because FILE was shared amongst them( thanks tye for pointing that out )

    I managed to pull of a quick replacement for that which works as one would expect.

    Notice the 9-$x , that is to make sure that time(thread1)>time(thread2)>time(thread3)>... .

    Also notice that $thread_lock are thread-specific locks

    use strict; use warnings; use threads; use feature 'say' ; use Fcntl qw(:flock); my $file_path = ">>/tmp/test.txt"; open(FILE, $file_path); for(0..9) { threads->new(\&worker, $_); } $_->join for threads->list; sub worker { my $x = shift; my $locked; open(my $thread_lock,$file_path); $locked = flock($thread_lock, LOCK_EX|LOCK_NB ); if( $locked ) { say "$x: lock acquired"; sleep 9-$x; } else { say "$x: cannot acquire lock"; }; if($locked) { flock( $thread_lock, LOCK_UN ); print "$x: lock released\n"; } return; }
    0: lock acquired 1: cannot acquire lock 2: cannot acquire lock 3: cannot acquire lock 4: cannot acquire lock 5: cannot acquire lock 6: cannot acquire lock 7: cannot acquire lock 8: cannot acquire lock 9: cannot acquire lock 0: lock released