How can I avoid running a python script multiple times?

Mongryong Mongryong at sympatico.ca
Tue Jan 28 12:08:45 EST 2003


One solution is locking on a file.  I call this a 'file mutex'.  So, in 
pseudocode, it would be something like this:

open mutex for desired lock file
acquire the mutex
....
processing
...
release the mutex

Fortunately, there's a convient solution to file locking for posix
platforms.  If you do, man 'fcntl' you should find out more.  There is
also a module for Python called 'fcntl'.  The exact replica!  Locking
works across threads and processes.

So using fcntl module:

import fcntl

lockFile = open("lock")
fcntl.lockf(lockFile.fileno(), fcntl.LOCK_EX) # acquire exlusive lock
...
process
...
fcntl.lockf(lockFile.fileno(), fcntl.LOCK_UN) # release lock

If you don't want to block on an exclusive lock acquire, change the
second parameter to 'fcntl.LOCK_EX | fcntl.LOCK_NB'.  Now, if the mutex
can't be acquired, an exception is thrown.

Note, fcntl is more like an 'recursive mutex'.  That is, if your process
already has the 'file mutex', it doesn't block.  Also, if your file
handler(ie. lockFile) is destroyed, the mutex is release.

I've created a wrapper class for 'fcntl' to that combines the mutex
capabilities with your standard file stream object.  This is useful if
you decide to port your code to another OS like Windows.

Here's the code again using my wrapper:

import filemutex

lockFile = filemutex.Open("lock", "r+") # can specify modes & buffer 
lockFile.acquire() # blocks
...
process
...
lockFile.release()

A non-blocking version:

lockFile = filemutex.Open("lock")
while 1:
	if lockFile.acquired(): # no blocking
		...process...
		lockFile.release()
	else:
		...do something else...
lockFile.close()

Note again, the mutex is recursive.

I use this for my web loggin and session management purposes.






More information about the Python-list mailing list