GHUM wrote:
hello,
in my application I am using
hSem = win32event.CreateSemaphore (None, 1,
1,"stringincludinginterfaceandport")
rt=win32event.WaitForSingleObject (hSem, 0)
if rt != win32event.WAIT_TIMEOUT:
really_do_start_my_app()
else:
print "application allready running"
to make sure that only ONE instance of the application is running at a
time. (as it implements a local webserver, that is necessary. Two
webservers listening on one port is bad)
Now I am going to make this application run on Linux. How can I get
similiar behaviour on Linux?
I know of the .pid files that get written by some server processes ...
BUT they do not get cleaned up on unclean shutdown of the application.
is there some better method?
Or some module which wraps the details of .pid-files quite nicely?
(like "trying to remove to check if other instance is still
running...., failing properly on missing write privs etc.)
You might consider using a cooperative file locking for that. I do this as
follows:
#-------------------------------------------------------------------------------
class LockFileCreationException(Exception):
pass
#-------------------------------------------------------------------------------
class LockObtainException(Exception):
pass
#-------------------------------------------------------------------------------
class LockFile(object):
def __init__(self, name, fail_on_lock=False, cleanup=True):
self.name = name
self.cleanup = cleanup
try:
self.fd = os.open(name, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
except OSError, e:
if e[0] == 2:
raise LockFileCreationException()
self.file = os.fdopen(self.fd, "w")
lock_flags = fcntl.LOCK_EX
if fail_on_lock:
lock_flags |= fcntl.LOCK_NB
try:
fcntl.flock(self.file, lock_flags)
except IOError, e:
if e[0] == 11:
raise LockObtainException()
raise
def __enter__(self):
return self.file
def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
self.file.close()
# we are told to cleanup after ourselves,
# however it might be that another process
# has done so - so we don't fail in that
# case.
if self.cleanup:
try:
os.remove(self.name)
except OSError, e:
if not e[0] == 2:
raise
You can use the LockFile as context, and either block until the lock is
released (which is most probably not what you want), or fail with
LockObtainException.
Diez