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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to