[python-uk] Semaphore and threading

Philip Herron redbrain at gcc.gnu.org
Sun Oct 7 13:42:03 CEST 2012


Hey

I am working on a little tool for myself recentl and had a bug that
was bothering me for ages. Kinda of a basic producer consumer problem.
The consumer was running in a thread:

self.__semaInvoke = threading.Semaphore (1)
self.__semaHandle = threading.Semaphore (0)

def run (self):
        self.__running = True
        while (self.__running):
            print "waiting"
            self.__semaHandle.acquire ()
            self.info ("Invoking %s" % self.__invoke)
            if self.__invoke == 'STOP':
                self.__running = False
            elif (self.__invoke in self.__steps) and \
                    hasattr (self, self.__invoke):
                self.__steps[self.__invoke] (self)
                self.__invoke = None
            else:
                self.info ("ERROR %s not valid command!" % \
                               self.__invoke)
                self.__running = False
            self.__invoke = None
            self.__semaInvoke.release ()
            print "released"
        self.close ()

Then i have a method to invoke which is the producer:

def invoke (self, cmd):
        if self.__running:
            self.__semaInvoke.acquire ()
            print "setting..."
            self.__invoke = cmd
            self.__semaHandle.release ()
            print "set + release!"

So the invoke method isnt in a thread as such just called from the
main thread since its embeded in a C program i call this method. But
the __semaHandle.release was never being released properly and the
consumer thread would hang untill i would invoke again. Then i simply
added time.sleep (1) at the end of the invoke thread and everything
worked perfectly. I reckon the ideal solution was to have the invoke
running in a thread or something but tried to keep it all simple as i
could. Just seemed to be some kind of race where the release would be
called but not fully released if it just returned after that method. I
bet it something to do with GIL in python where the request to release
is in a que since the consumer is trying to read it or something at
the same time.maybe a mutex might help but not sure. Just what i
noticed anyway.

I think if i had the producer in its own thread as well i think this
would solve the problem. But the whole idea was to have my C program
calling bla.invoke (). But this seems to not produce the results i
wanted. Seems just time.sleep fixes everything just making sure things
are set but its not a concrete solution wonder has anyone else seen
this.

--Phil


More information about the python-uk mailing list