Singleton process

R

Roy Johnson

I've got a program that I want to be the only instance of itself
running at any given time. The method I've chosen for doing that is
probably not the preferred method, and it certainly won't work under
Windows.

Here's what I'm doing:
### Ensure that this is the only instance running
my @myprocs = grep(/perl $0/, `ps -f`);
for (@myprocs) {
my ($pid) = (split)[1];
next if ($pid == $$);
die "Found $_\n";
}

What *should* I be doing, for maximum reliability on both Unix and
Windows?
 
T

Tassilo v. Parseval

Also sprach Roy Johnson:
I've got a program that I want to be the only instance of itself
running at any given time. The method I've chosen for doing that is
probably not the preferred method, and it certainly won't work under
Windows.

Here's what I'm doing:
### Ensure that this is the only instance running
my @myprocs = grep(/perl $0/, `ps -f`);
for (@myprocs) {
my ($pid) = (split)[1];
next if ($pid == $$);
die "Found $_\n";
}

What *should* I be doing, for maximum reliability on both Unix and
Windows?

Locking, I guess. Let the program create a lockfile at the beginning:

use Fcntl;

sysopen LOCK, "/tmp/prog.lock", O_CREAT|O_EXCL or
exit 1;

...

END { unlink "/tmp/prog.lock" }

This should be portable between UNIX and Windows.

Tassilo
 
B

Ben Morrow

Also sprach Roy Johnson:


Locking, I guess. Let the program create a lockfile at the beginning:

use Fcntl;

sysopen LOCK, "/tmp/prog.lock", O_CREAT|O_EXCL or
exit 1;

...

END { unlink "/tmp/prog.lock" }

This should be portable between UNIX and Windows.

What if the process is killed and leaves a stale lockfile around?
You want to flock() the file as well; this will be broken when the
process dies, at least on Unix. Not sure about Windows: I've had nasty
experiences with programs dieing and leaving locks locked... :(

Ben
 
T

Tassilo v. Parseval

Also sprach Ben Morrow:
What if the process is killed and leaves a stale lockfile around?
You want to flock() the file as well; this will be broken when the
process dies, at least on Unix. Not sure about Windows: I've had nasty
experiences with programs dieing and leaving locks locked... :(

Define a signal-handler for a couple of signals (this however is not
quite so portable any longer). Anyway, stale lockfiles are nothing
special and show up once in a while.

Another approach would be to let the processes write their PIDs into the
file. That way, a new process could see whether a) any PIDs are to be
found in it and b) whether processes belonging to this PID are still
alive (by sending signal 0).

Other than that I don't expect Perl scripts to continuously crash. At
least mine don't.

Tassilo
 
B

Bart Lateur

Ben said:
What if the process is killed and leaves a stale lockfile around?
You want to flock() the file as well; this will be broken when the
process dies, at least on Unix. Not sure about Windows:

Just flocking a file, that would be my idea. Whether it works on
Windows, depends on the version of Windows. Win98 and friends don't do
flock(). NT can, I think.
 
B

Bart Lateur

Mark said:
Can I suggest the following delightful and foolproof solution to this
problem?

http://perl.plover.com/yak/flock/samples/slide006.html

Hmm... I can think of systems that refuse to flock files exclusively
when they're not opened for writing. Neither of the above examples
complies to that condition.

See paragraph 6 in

<http://www.perldoc.com/perl5.8.0/pod/func/flock.html>

Note that the fcntl(2) emulation of flock(3) requires that
FILEHANDLE be open with read intent to use LOCK_SH and requires
that it be open with write intent to use LOCK_EX.
 
B

Ben Morrow

(e-mail address removed) (Mark Jason Dominus) wrote in message


For some reason, both suggestions (using $0 and using DATA) fail on my
Unix box. I am using flock, though, and when I create a throwaway file
for the purpose, it works properly.

Out of interest: which Unix are you on, what error do you get, and
does your perl use flock() or fcntl() locking (if you can tell)?

Ben
 
R

Roy Johnson

Ben Morrow said:
Out of interest: which Unix are you on, what error do you get, and
does your perl use flock() or fcntl() locking (if you can tell)?

I'm on Solaris (5.8).
The error message I get is
Bad file number

I don't know how to check which form of locking is being done. Here's
a sample program:

#!perl

use strict;
use warnings;

use Fcntl ':flock';
open SELF, $0 or die "Could not open $0: $!\n";
flock SELF, LOCK_EX | LOCK_NB
or die "Could not flock $0: $!\n";
close SELF;
print "Done\n";
 
C

ctcgag

I'm on Solaris (5.8).
The error message I get is
Bad file number

I don't know how to check which form of locking is being done. Here's
a sample program:

#!perl

use strict;
use warnings;

use Fcntl ':flock';
open SELF, $0 or die "Could not open $0: $!\n";
flock SELF, LOCK_EX | LOCK_NB
or die "Could not flock $0: $!\n";
close SELF;
print "Done\n";

I get the same thing on my version of perl on that OS. changing it to open
SELF, "+<$0" worked.

Apparently this is an instance of the "can't lock exclusively if you don't
intend to write" issue.

Xho
 
J

JR

I'm on Solaris (5.8).
The error message I get is
Bad file number

I don't know how to check which form of locking is being done. Here's
a sample program:

#!perl

use strict;
use warnings;

use Fcntl ':flock';
open SELF, $0 or die "Could not open $0: $!\n";
flock SELF, LOCK_EX | LOCK_NB
or die "Could not flock $0: $!\n";
close SELF;
print "Done\n";

This is one way to check which form of locking your system supports.
This may be useful to you.

#!/perl/ -w
use strict;
use IO::File;
use Fcntl ":flock";

*FH1 = new_tmpfile IO::File or die "Can't open: $!\n";

eval {flock FH1, LOCK_SH};
die "No locks supported.\n" if $@;

open FH2, ">>&FH1" or die "Can't open: $!\n";

(flock FH2, LOCK_SH|LOCK_NB) ? print "Shared locks supported.\n" :
print "Shared locks not supported.\n";

(flock FH2, LOCK_EX|LOCK_NB) ? print "Exclusive locks supported.\n" :
print "Exclusive locks not supported.\n";
 
B

Ben Morrow

This is one way to check which form of locking your system supports.
This may be useful to you.

<snip test for shared/exclusive lock support>

That wasn't the question. There are two ways of locking files under
Unix, using the flock(2) or fcntl(2) syscalls. Perl can (generally
speaking) be built to use either. I was asking which.

AFAIK, all forms of locking support both shared and exclusive locks:
seems pretty useless to me if they don't...

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,266
Messages
2,571,077
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top