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


in reply to singleton lock not reliable

First thing I thought of was shared memory. In IPC::Shareable, if one attempts to create a shared memory segment that has already been created in a separate process with exclusive set, the second process will croak(). So what I did is add a graceful flag to its options, and when set, the second process that tries to create the exclusive segment simply exits gracefully with no noise or anything. Observe:

lock.pl:

use warnings; use strict; use IPC::Shareable; tie my $lock, 'IPC::Shareable', { key => 'LOCK', create => 1, exclusive => 1, destroy => 1, graceful => 1 }; $lock = $$; print "procID: $lock\n"; sleep 5;

Run it in one window:

spek@scelia ~/scratch $ perl lock.pl procID: 21241

...it sleeps for a few seconds, during which we run it in the second window:

spek@scelia ~/repos/ipc-shareable $ perl ~/scratch/lock.pl spek@scelia ~/repos/ipc-shareable $

...it exited before it printed anything. After the five second sleep in proc one is done, run it in window two:

spek@scelia ~/repos/ipc-shareable $ perl ~/scratch/lock.pl procID: 21339

So, in essence, this question prompted me to update the distribution to handle your very issue, ummm, well, gracefully. I just published it, so it may not yet be available at your mirror. Version 1.01 has the new 'graceful' feature.

Replies are listed 'Best First'.
Re^2: singleton lock not reliable
by stevieb (Canon) on Jun 25, 2021 at 15:43 UTC

    I've done one better. I've added a singleton() method. Its specifically designed to prevent more than one instance of any script (or processes that share the same shared memory segment). It's trivial to use, as it hides all of the various flags:

    use IPC::Shareable; IPC::Shareable->singleton('LOCK'); # Do scripty perl stuff here

    That's it. You can now be guaranteed that if a second instance of the script starts, it'll exit gracefully immediately as soon as singleton() is called.

    You can also tell it to emit a notice that the script is exiting by sending in a true value as the second 'warn' param:

    IPC::Shareable->singleton('LOCK', 1);

    If a second instance is run, the following will be thrown:

    Process ID 14784 exited due to exclusive shared memory collision

    Version 1.03 has this update.

      Good, better, best!

      I released a new distribution, Script::Singleton that ensures only a single instance of a script can run at any time. No methods or flags to use, you simply:

      use Script::Singleton 'LOCK';

      That's it! LOCK is the glue/key that identifies the shared memory segment. As with my last update, send in a true value to get a warning if a second instance of a script tries to run but has to exit:

      use Script::Singleton 'LOCK', 1;