translating "create Semaphore" to Linux

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • GHUM

    translating "create Semaphore" to Linux

    hello,

    in my application I am using

    hSem = win32event.Crea teSemaphore (None, 1,
    1,"stringinclud inginterfaceand port")
    rt=win32event.W aitForSingleObj ect (hSem, 0)
    if rt != win32event.WAIT _TIMEOUT:
    really_do_start _my_app()
    else:
    print "applicatio n 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
  • Diez B. Roggisch

    #2
    Re: translating "create Semaphore" to Linux

    GHUM wrote:
    hello,
    >
    in my application I am using
    >
    hSem = win32event.Crea teSemaphore (None, 1,
    1,"stringinclud inginterfaceand port")
    rt=win32event.W aitForSingleObj ect (hSem, 0)
    if rt != win32event.WAIT _TIMEOUT:
    really_do_start _my_app()
    else:
    print "applicatio n 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 LockFileCreatio nException(Exce ption):
    pass


    #-------------------------------------------------------------------------------

    class LockObtainExcep tion(Exception) :
    pass


    #-------------------------------------------------------------------------------

    class LockFile(object ):

    def __init__(self, name, fail_on_lock=Fa lse, 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 LockFileCreatio nException()
    self.file = os.fdopen(self. fd, "w")
    lock_flags = fcntl.LOCK_EX
    if fail_on_lock:
    lock_flags |= fcntl.LOCK_NB
    try:
    fcntl.flock(sel f.file, lock_flags)
    except IOError, e:
    if e[0] == 11:
    raise LockObtainExcep tion()
    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
    LockObtainExcep tion.

    Diez

    Comment

    • Francesco Bochicchio

      #3
      Re: translating "create Semaphore" to Linux

      On 29 Ago, 13:28, GHUM <haraldarminma. ..@gmail.comwro te:
      hello,
      >
      in my application I am using
      >
      hSem = win32event.Crea teSemaphore (None, 1,
      1,"stringinclud inginterfaceand port")
      rt=win32event.W aitForSingleObj ect (hSem, 0)
      if rt != win32event.WAIT _TIMEOUT:
         really_do_start _my_app()
      else:
         print "applicatio n 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
      ----
      FB

      Comment

      • Tim Golden

        #4
        Re: translating &quot;create Semaphore&quot; to Linux

        GHUM wrote:
        hSem = win32event.Crea teSemaphore (None, 1,
        1,"stringinclud inginterfaceand port")
        rt=win32event.W aitForSingleObj ect (hSem, 0)
        if rt != win32event.WAIT _TIMEOUT:
        really_do_start _my_app()
        else:
        print "applicatio n 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

        Comment

        • GHUM

          #5
          Re: translating &quot;create Semaphore&quot; to Linux

          Tim,
          ... why use a Semaphore rather than a Mutex?
          as much as I understood the documentation at MSDN

          You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes.

          The following example uses a semaphore object to limit the number of threads that can perform a particular task.


          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 <someotherhttps serverframework iuse>; 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


          Comment

          • Tim Golden

            #6
            Re: translating &quot;create Semaphore&quot; to Linux

            GHUM wrote:
            Tim,
            >
            >... why use a Semaphore rather than a Mutex?
            >
            as much as I understood the documentation at MSDN
            >
            You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes.

            The following example uses a semaphore object to limit the number of threads that can perform a particular task.

            >
            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...
            >
            >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.
            Fair enough.

            TJG

            Comment

            Working...