translating "create Semaphore" to Linux
Diez B. Roggisch
deets at nospam.web.de
Fri Aug 29 07:46:30 EDT 2008
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
More information about the Python-list
mailing list