Avoiding running a process twice

E

Ed W

This is almost certainly an FAQ quality question and I appologise in
advance, but could anyone point me to some references on how to avoid
allowing the user to run multiple instances of my app. I'm looking for
something cross platform, Win32 and linux.

The idea is that the app is a socket app and users will confuse themselves
if they can fire up multiple instances simultaneously. I would like to
detect that there already a running instance and if so, then bail out.

The root seems to be to find a nice generic way of checking the process
table? What are the best modules for this under Win32?

Thanks for any pointers

Ed W
 
A

Anno Siegel

Ed W said:
This is almost certainly an FAQ quality question and I appologise in
advance, but could anyone point me to some references on how to avoid
allowing the user to run multiple instances of my app. I'm looking for
something cross platform, Win32 and linux.

The idea is that the app is a socket app and users will confuse themselves
if they can fire up multiple instances simultaneously. I would like to
detect that there already a running instance and if so, then bail out.

The root seems to be to find a nice generic way of checking the process
table? What are the best modules for this under Win32?

I don't think you want to check the process table. That isn't even portable
among unix systems, and it may introduce race conditions.

One common way is to sync through the filesystem. Use existence of a file
as a signal that a process is up. Create the file at startup, and delete
it in an END block. Using sysopen() (q.v.) for creation should make that
reasonably safe.

If you can use file locking (not sure about the windows side), that would
be the way to go. Again you use a file, but it isn't created/deleted
with program runs, but only locked (exclusively). The advantage is that
it's easier to get correct (because it's what locking is about), and
you're not responsible for deleting the file. The system takes care
of the lock.

Nothing of this is particular to Perl, the solutions apply more-or-less
to a process written in any language.

Anno
 
S

Sam Holden

[snip]
how to avoid
allowing the user to run multiple instances of my app. I'm looking for
something cross platform, Win32 and linux.

[snip]

Ed, Here's what I use checking for new virus dat files at NAI:

# Set flag file to see if process is already running
$flagfile = "c:/test/virusflagfile";

That certainly is not cross platform. Unless you have a very strange linux
file system with c:/test existing in all directories.
# Check to see if process is already running
if (!-e $flagfile ) { &createflag; # If it doesn't exist, create one

There's an obvious race condition there. So the technique doesn't
stop multiple instances running at once.

# Do your processes HERE!!!!!!!!!!!

# Clear flag file so process can run again
&deleteflag;}

And what happens if the process is terminated some how (the power cord is
kicked out of the machine, for example) before it executes deleteflag?
So the technique will also stop any instance running...

This seems an amazingly bad way of doing job.
# If this process is already running - Exit
else { exit; }

sub createflag {
open (FLAG,">>$flagfile") or die "Can't open $flagfile: $!\n";
}

sub deleteflag {
close (FLAG) or die "Can't close $flagfile: $!\n";
unlink $flagfile;
}

And why are you using &createflag, instead of createflag()? You
certainly don't seem to use the current @_ in the subroutine?
 
E

Ed W

If you can use file locking (not sure about the windows side), that would
be the way to go. Again you use a file, but it isn't created/deleted
with program runs, but only locked (exclusively). The advantage is that
it's easier to get correct (because it's what locking is about), and
you're not responsible for deleting the file. The system takes care
of the lock.

Could you show me a perl example of this in action perhaps? A unix version
would be fine

Thanks
 
A

Anno Siegel

Ed W said:
Could you show me a perl example of this in action perhaps? A unix version
would be fine

Uh, no. To write one would require me to look things up in the
documentation. I prefer you do that. But thanks for not requiring
a windows version.

Also, you might have left an attribution (vulgo, indicated who you're
talking to).

Anno
 
S

Simon Andrews

Anno said:
If you can use file locking (not sure about the windows side), that would
be the way to go. Again you use a file, but it isn't created/deleted
with program runs, but only locked (exclusively). The advantage is that
it's easier to get correct (because it's what locking is about), and
you're not responsible for deleting the file. The system takes care
of the lock.

A nice little idea someone posted here was to get an exclusive lock on
the script itself to make sure only one instance was running. I never
tried it, but it seemed like a nice way to do this as you don't have to
remember which file you're locking for a particular script, you just
lock the script itself.

Having said this, the flock documentation says that:

[lockf] requires that FILEHANDLE be open with write intent

Would this not mean you'd have to open your script for appending? If so
I'd be less happy about this approach as it would mean each person using
it would have to have write permission to it.

This would presumably mess up the other similar suggestion, which was to
lock the DATA filehandle.
 
A

Anno Siegel

Simon Andrews said:
Anno said:
If you can use file locking (not sure about the windows side), that would
be the way to go. Again you use a file, but it isn't created/deleted
with program runs, but only locked (exclusively). The advantage is that
it's easier to get correct (because it's what locking is about), and
you're not responsible for deleting the file. The system takes care
of the lock.

A nice little idea someone posted here was to get an exclusive lock on
the script itself to make sure only one instance was running. I never
tried it, but it seemed like a nice way to do this as you don't have to
remember which file you're locking for a particular script, you just
lock the script itself.

Having said this, the flock documentation says that:

[lockf] requires that FILEHANDLE be open with write intent

Right, on some systems require this, including mainstream ones (solaris).
That requirement is short-sighted design, imho. It assumes that a file
lock always protects exactly the file it is locking. Our example shows
that other kinds of locking occur where the requirement makes no sense.
Would this not mean you'd have to open your script for appending? If so
I'd be less happy about this approach as it would mean each person using
it would have to have write permission to it.

To be portable, yes. It also means you have to *find* the binary first
to open it for writing, not something you want to do if you don't have to.
This would presumably mess up the other similar suggestion, which was to
lock the DATA filehandle.

Right. Locking DATA exclusively won't work everywhere.

This discussion illustrates a general principle. In programming as in
other crafts, it is often tempting to use something you "happen to have
around" for some other purpose. Like you have a box to mount on the
wall, and you find a bolt sticking out that holds a box on the other
side. "Let's use that!" Think twice before you do it. It *may*
be a good idea, but you create dependencies that wouldn't be there
without it.

Anno
some other purpose.
 
A

Anno Siegel

Simon Andrews said:
Anno said:
If you can use file locking (not sure about the windows side), that would
be the way to go. Again you use a file, but it isn't created/deleted
with program runs, but only locked (exclusively). The advantage is that
it's easier to get correct (because it's what locking is about), and
you're not responsible for deleting the file. The system takes care
of the lock.

A nice little idea someone posted here was to get an exclusive lock on
the script itself to make sure only one instance was running. I never
tried it, but it seemed like a nice way to do this as you don't have to
remember which file you're locking for a particular script, you just
lock the script itself.

Having said this, the flock documentation says that:

[lockf] requires that FILEHANDLE be open with write intent

Right, on some systems require this, including mainstream ones (solaris).
That requirement is short-sighted design, imho. It assumes that a file
lock always protects exactly the file it is locking. Our example shows
that other kinds of locking occur where the requirement makes no sense.
Would this not mean you'd have to open your script for appending? If so
I'd be less happy about this approach as it would mean each person using
it would have to have write permission to it.

To be portable, yes. It also means you have to *find* the binary first
to open it for writing, not something you want to do if you don't have to.
This would presumably mess up the other similar suggestion, which was to
lock the DATA filehandle.

Right. Locking DATA exclusively won't work everywhere.

This discussion illustrates a general principle. In programming as in
other crafts, it is often tempting to use something you "happen to have
around" for some other purpose. Like you have a box to mount on the
wall, and you find a bolt sticking out that holds a box on the other
side. "Let's use that!" Think twice before you do it. It *may*
be a good idea, but you create dependencies that wouldn't be there
without it.

Anno
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

(e-mail address removed)-berlin.de (Anno Siegel) wrote in
Simon Andrews said:
Anno Siegel wrote:

A nice little idea someone posted here was to get an exclusive lock
on the script itself to make sure only one instance was running. I
never tried it, but it seemed like a nice way to do this as you don't
have to remember which file you're locking for a particular script,
you just lock the script itself.

Having said this, the flock documentation says that:

[lockf] requires that FILEHANDLE be open with write intent

Right, on some systems require this, including mainstream ones
(solaris). That requirement is short-sighted design, imho. It assumes
that a file lock always protects exactly the file it is locking. Our
example shows that other kinds of locking occur where the requirement
makes no sense.

Aha!! That clears up a longstanding confusion on my part.

Some time ago, I attended a lightning talk by Mark Dominus, in which he
illustrated the "lock DATA" method of ensuring exclusivity. I went to
work the next day and tried it, on a Solaris machine. I never got it to
work, and I never figured out why.

Thanks, Anno.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP8NHeGPeouIeTNHoEQJCIACfVRer1jF1myGJQE6678HpX5AHqskAoOrC
WU+VcLgwchew922H8FD7Y4I1
=m6yK
-----END PGP SIGNATURE-----
 

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

Forum statistics

Threads
474,142
Messages
2,570,819
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top