Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>But what will you do while someone else has the lock? Quit and try later? Busy-wait?</p> <p>If you don't need synchronization, then a good bet is <a href="http://perldoc.perl.org/functions/sysopen.html" rel="nofollow noreferrer"><code>sysopen</code></a> with the <code>O_EXCL</code> and <code>O_CREAT</code> flags set, which will create the file only if it doesn't exist.</p> <pre><code>use Fcntl qw/ :DEFAULT /; # ... sysopen my $fh, $LOCKFILE, O_EXCL|O_CREAT or die "$0: sysopen: $!"; </code></pre> <p>But note the following caveat from the Linux <code>open(2)</code> manual page:</p> <blockquote> <p><code>O_EXCL</code> is only supported on NFS when using NFSv3 or later on kernel 2.6 or later. In environments where NFS <code>O_EXCL</code> support is not provided, programs that rely on it for performing locking tasks will contain a race condition. Portable programs that want to perform atomic file locking using a lockfile, and need to avoid reliance on NFS support for <code>O_EXCL</code>, can create a unique file on the same file system (<em>e.g.</em>, incorporating hostname and PID), and use <code>link(2)</code> to make a link to the lockfile. If <code>link(2)</code> returns 0, the lock is successful. Otherwise, use <code>stat(2)</code> on the unique file to check if its link count has increased to 2, in which case the lock is also successful.</p> </blockquote> <p>“I’d rather have a network filesystem than NFS,” as the saying goes, so keep your coordinating processes on the same machine if you can.</p> <p>You might consider using <a href="http://perldoc.perl.org/functions/flock.html" rel="nofollow noreferrer"><code>flock</code></a> as in the code below:</p> <pre><code>#! /usr/bin/perl use warnings; use strict; use Fcntl qw/ :DEFAULT :flock /; my $LOCKFILE = "/tmp/mylock"; sub acquire_lock { sysopen my $fh, $LOCKFILE, O_RDWR|O_CREAT or die "$0: open: $!"; flock $fh, LOCK_EX or die "$0: flock: $!"; $fh; } sub work { for (1 .. 2) { my $fh = acquire_lock; print "$0: $$ has lock\n"; sleep rand 3; close $fh or warn "$0: [$$] close: $!"; } exit; } </code></pre> <p>For a demo, the code below forks five children that take turns acquiring the lock:</p> <pre><code>my $KIDS = 5; my %pids; for (1 .. $KIDS) { my $pid = fork; die "$0: fork: $!" unless defined $pid; $pid ? ++$pids{$pid} : work; } while (my $pid = wait) { last if $pid == -1; warn "$0: unknown child $pid" unless delete $pids{$pid}; } warn "$0: still alive: " . join(", " =&gt; sort { $a &lt;=&gt; $b } keys %pids) . "\n" if keys %pids; </code></pre> <p>Sample output:</p> <pre>./kidlock: 26644 has lock ./kidlock: 26645 has lock ./kidlock: 26646 has lock ./kidlock: 26645 has lock ./kidlock: 26648 has lock ./kidlock: 26646 has lock ./kidlock: 26647 has lock ./kidlock: 26647 has lock ./kidlock: 26644 has lock ./kidlock: 26648 has lock</pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload