translating "create Semaphore" to Linux

G

GHUM

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.)

best wishes,

Harald
 
D

Diez B. Roggisch

GHUM said:
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
 
F

Francesco Bochicchio

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.)

best wishes,

Harald

The best way I know to do it is to use fnctl.flock or fcntl.lockf
functions. I never used it, so can just point you to the
official documentation. The idea is that your applications should take
exclusive access to one of the application files, so that if it is
started a second time, the second run will find the file locked and
understand that there is an instance started.
AFAIK, if the process locking a files dies, the OS releases the lock,
so there is no possibility of stale locks (check this!).

Anyway, you could simply use your server socket as lock. It is not
possible to have two processes accepting connections on the same port,
the second process would receive an error 'Address already in use'.
You could use it as signal that there is
already an instance of the application running. This method should be
available in both Windows and Linux (and various
Unix flavours too), so your code would be more portable.

Ciao
 
T

Tim Golden

GHUM said:
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.


Running a serious risk of teaching my grandmother, but...

.... why use a Semaphore rather than a Mutex? Or why not
simply use the bound socket as its own mutex? I know
Windows won't allow you to rebind the same socket to the
same addr/port in two different processes (unless perhaps
you play some trickery with the socket options).

TJG
 
G

GHUM

Tim,
... why use a Semaphore rather than a Mutex?

as much as I understood the documentation at MSDN

http://msdn.microsoft.com/en-us/library/ms686927(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms686946(VS.85).aspx

a mutex seems to be nothing else than a special case of a semaphore?
That is, a semaphore can be created to allow MAX_SEM_COUNT concurrent
runners, and MUTEX defaults to one and only one ...

The other api-spells are identical, like wait_for_xxxx...; so propably
I stumbled on the working Semaphore Code before, or in some ancient
win32 wrapper createMutex was not documented or something in that
aspect:)
Or why notsimply use the bound socket as its own mutex? I know
Windows won't allow you to rebind the same socket to the
same addr/port in two different processes (unless perhaps
you play some trickery with the socket options).

My experience was that this is correct for certain values of "allow"
and "trickery". Sometimes the binding seems to get allowed but does
not work. Main reason is that the socket-bind happens somewhere in
medusa or <someotherhttpsserverframeworkiuse>; so to use it as a
semaphore I would have to dig there. I am not totally sure what
trickery on socket is played down there; and I prefer to stay as far
away as possible from that area.

Harald
 
T

Tim Golden

GHUM said:
Tim,


as much as I understood the documentation at MSDN

http://msdn.microsoft.com/en-us/library/ms686927(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms686946(VS.85).aspx

a mutex seems to be nothing else than a special case of a semaphore?
That is, a semaphore can be created to allow MAX_SEM_COUNT concurrent
runners, and MUTEX defaults to one and only one ...

The other api-spells are identical, like wait_for_xxxx...; so propably
I stumbled on the working Semaphore Code before, or in some ancient
win32 wrapper createMutex was not documented or something in that
aspect:)

I think it hardly matters except that someone (like me :) )
coming to your code who's familiar with the uses of mutex
and semaphore elsewhere -- they're not Microsoft inventions
as I'm sure you realise -- will be a little stumped by the
fact that a mutex is pretty much the canonical recipe for
allowing only one instance of an app, yet you're using a
semaphore which can be used for slightly different
purposes. I'd be wondering whether you had some more
sophisticated model in mind which I was unable to fathom...
My experience was that this is correct for certain values of "allow"
and "trickery". Sometimes the binding seems to get allowed but does
not work.

Fair enough.

TJG
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top