473,405 Members | 2,187 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Making sure script only runs once instance at a time.

I have written a script and I would like to ensure that the script is
never run more than once at any given time.

What is the best way of testing and exiting if there is another version
of this script running somewhere on this machine?

I guess what I'm asking is how to handle system processes the way I can
in shell. I am running this on linux.
Thanks

-h

--
Hari Sekhon

Sep 27 '06 #1
11 3156
In message <ma**************************************@python.o rg>, Hari
Sekhon wrote:
I have written a script and I would like to ensure that the script is
never run more than once at any given time.
<http://groups.google.co.nz/gr***********************************@lust.ihug.co .nz>
Sep 28 '06 #2
Hari Sekhon wrote:
I have written a script and I would like to ensure that the script is
never run more than once at any given time.

What is the best way of testing and exiting if there is another version
of this script running somewhere on this machine?

I guess what I'm asking is how to handle system processes the way I can
in shell. I am running this on linux.
Although the other solution suggested seems to be more general (I have not
read the code, only the info in the header), the following may be
sufficient for what you want, and can be used as code inside of your
script. It searches /proc/ for another process that is a script interpreted
by python and has the same name as your script. So it can fail, if there is
another python script running with the same name, but which is not
identical to your script. OTOH it's a very short and simple test:

-----
#!/bin/env python

import os.path
import linecache

pid=os.getpid()
script=linecache.getline(os.path.join('/proc', str(pid), 'cmdline'),
1).split('\0')[0:2]
for pid in filter(lambda x: x.isdigit() and x != str(pid),
os.listdir('/proc')):
other=linecache.getline(os.path.join('/proc', str(pid), 'cmdline'),
1).split('\0')[0:2]
if script[0] == other[0] and os.path.basename(script[-1]) ==
os.path.basename(other[-1]):
raise "already running!"
-----

HTH
Stephan

Sep 29 '06 #3
MaR
A very brutal but simple and effective method is to bind() to a socket
on localhost eg (127.0.0.1, 4711), listen() but never accept().
Any other process trying to to bind() on the same port will fail..
When the process dies, the port is released automatically, pending som
timedelay..

But this assumes you have an execution environment where this is
acceptable. A sysadmin may have objections ;o)

Sep 29 '06 #4
Seeing as there doesn't seem to be a good answer to this (or at least
not one that we have so far some up with) I have decided to fall back to
my old friend the unix shell. It's as portable as python, but is very
flexible and fast at doing real things and will tell me if another
process by this name is running. If so, print msg and exit. simple.

-h

Hari Sekhon

MaR wrote:
A very brutal but simple and effective method is to bind() to a socket
on localhost eg (127.0.0.1, 4711), listen() but never accept().
Any other process trying to to bind() on the same port will fail..
When the process dies, the port is released automatically, pending som
timedelay..

But this assumes you have an execution environment where this is
acceptable. A sysadmin may have objections ;o)

Sep 29 '06 #5
Hari Sekhon <hp******@googlemail.comwrites:
Seeing as there doesn't seem to be a good answer to this (or at least
not one that we have so far some up with) I have decided to fall back
to my old friend the unix shell. It's as portable as python, but is
very flexible and fast at doing real things and will tell me if
another process by this name is running. If so, print msg and
exit. simple.
Huh? The obvious way to check for another instance is with a lock
file. Just open the file and use fcntl to set an exclusive lock. If
the lock acquisition fails, another instance has the file.
Sep 29 '06 #6
Hari Sekhon wrote:
I'm not sure if that is a very old way of doing it, which is why I was
reluctant to do it. My way actually uses the process list of the os
(linux) and counts the number of instances. If it is more than 0 then
another process is running and the script exits gracefully.
the code that reliably identifies instances of a given program would be
interesting to see.
Also, apart from the fact the using lockfiles feels a bit 1970s, I have
found that in real usage of other programs within the company that use
lockfiles, it sometimes causes a bit of troubleshooting time when
it stops working due to a stale lockfile.
to minimize that risk, store the pid in the lockfile (and preferrably
also the host name), and make sure that the program checks that the pid
is still active before it "stops working".

</F>

Sep 29 '06 #7
Hari Sekhon wrote:
How exactly do you check that the pid is still active in python? Is
there a library or something that will allow me to manipulate system
processes and listings etc the way everybody does in unix shells....
by passing zero to the os.kill primitive:

os.kill(pid, 0)

if this raises an OSError, there's no active process with the given pid.
I'm a huge fan of shell so I've done my own thing which leans on shell
as follows:

import sys,commands,os

scriptpath = sys.argv[0]
scriptname = os.path.basename(scriptpath)

number_procs=commands.getstatusoutput('ps -ef|grep %s|grep -v grep|wc
-l' % scriptpath)

if number_procs 1:
print "There appears to be another %s process running." % scriptname
what if you have commands with overlapping names (e.g. "bar.py" and
"foobar.py"), or some other user on the machine happens to run a
command that, on purpose or by accident, contains your script's name
(e.g. "emacs mybar.py") ?

</F>

Oct 2 '06 #8
Here's a class using Fredrik's suggestions to provide generic,
cross-platform file locking (only tested on *nix however, with the two
test files listed [i.e., run test1.py in one terminal then test2.py in
another]):

http://pastie.caboo.se/15851

Ps. The lockfile should also always be cleaned up (even when your
program excepts) because of the magic __del__ method, but I don't
guarentee it will be (nor depend on it: I used the pid + hostname in
the lockfile approach).

Regards,
Jordan

Oct 2 '06 #9
MonkeeSage wrote:
Here's a class using Fredrik's suggestions to provide generic,
cross-platform file locking (only tested on *nix however, with the two
test files listed [i.e., run test1.py in one terminal then test2.py in
another]):

http://pastie.caboo.se/15851

Ps. The lockfile should also always be cleaned up (even when your
program excepts) because of the magic __del__ method, but I don't
guarentee it will be (nor depend on it: I used the pid + hostname in
the lockfile approach).
the problem with this solution is that it does not handle the read
nonexclusive/write exclusive locking model. In this model, reads don't
block, they only register that the request is in process. writes lock
request block until all outstanding reads have completed. When there is
a write lock waiting, all subsequent reads lock requests block until the
write has completed.

Things get more complicated when you add exclusive read capability to
the system. But fortunately, that capability isn't needed very often
and sometimes reduces to a write exclusive lock.

The next level up in terms of locking system requirements is some form
of scoreboard mechanism where you can lock individual records in a file
(i.e. dbm). I do something like this in a demon which owns the dbm,
mediates database access, and record locking so that I can have multiple
readers and writers at the same time using gdbm. But you can also use
the same technique for metakit.
---eric
Oct 3 '06 #10
Eric S. Johansson wrote:
the problem with this solution is that it does not handle the read
nonexclusive/write exclusive locking model. In this model, reads don't
block, they only register that the request is in process. writes lock
request block until all outstanding reads have completed. When there is
a write lock waiting, all subsequent reads lock requests block until the
write has completed.
I should have said "lock file" -- I'm not trying to do file locking for
concurrent access to a file; I'm trying to provide a lock file to
determine if an instance of a process is already spawned.

Regards,
Jordan

Oct 3 '06 #11
MonkeeSage wrote:
Eric S. Johansson wrote:
>the problem with this solution is that it does not handle the read
nonexclusive/write exclusive locking model. In this model, reads don't
block, they only register that the request is in process. writes lock
request block until all outstanding reads have completed. When there is
a write lock waiting, all subsequent reads lock requests block until the
write has completed.

I should have said "lock file" -- I'm not trying to do file locking for
concurrent access to a file; I'm trying to provide a lock file to
determine if an instance of a process is already spawned.
That difference was clear to me and I appreciate your comment clarifying
the issue further.

I was trying to point out how there are more models of locking that we
could use in Python than the single point lock as you had described.
Unfortunately, most system locks are hard to get right and difficult to
test so you're never quite sure until something breaks and then you know
you did it wrong.

I really should grab the code you pasted and use it as a rewrite for
portalocker. Someday. <sigh>

--- eric

Oct 3 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: droog | last post by:
hi group! I am new to PHP and so far managed to find my answers by searching this group instead of posting repeating questions, but I don't know what to search for to get answer to this...
8
by: Rob Ristroph | last post by:
I have tried out PHP 5 for the first time (with assistance from this group -- thanks!). The people I was working with have a site that uses lots of php objects. They are having problems with...
0
by: |-|erc | last post by:
Hi! Small challenge for you. The index.php uses this file and calls layout(). Take a look at www.chatty.net this file draws the chat login box on the right. I traced the CHAT button it submits...
7
by: Arun | last post by:
Hi, This is a scripting question, but since I am writing the script in python I am posting this question here: I have a python script that runs a simulator (that was written in c++, so I use...
5
by: Boris Nikolaevich | last post by:
This is backwards of what I usually want--normally if you have a long-running ASP script, it's a good idea to check to see whether the client is still connected so you can cancel execution. ...
7
by: C.Joseph Drayton | last post by:
I have a problem that I am hoping someone can help me with. First let me describe the problem. I have an HTML form that in one field has an onBlur call to a JavaScript function. When you exit the...
5
by: Daniel | last post by:
Hey guys What is the best way in c# to ensure that once your app is running, if the user then clicks to run it again it notifies them it is already running, or alternatively, brings the running...
16
by: Andrea Gavana | last post by:
Hi Diez & All, Do you mind explaining "why" you find it *buttugly*? I am asking just out of curiosity, obviously. I am so biased towards wxPython that I won't make any comment on this thread...
11
by: Rafe | last post by:
Hi, I'm working within an application (making a lot of wrappers), but the application is not case sensitive. For example, Typing obj.name, obj.Name, or even object.naMe is all fine (as far as...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.