SkylineGodzilla SkylineGodzilla - 3 months ago 17
Python Question

Python threading sync

I have a base class that has an empty method called

Update
.
This
Update
method is inherited by X amount of different subclasses
The base class calls the
Update
method once every 30 ticks (right now it's not. It's just doing it in a loop right now, but I plan to make it get called every 30 ticks soon.)
Each subclass has its own method
Update
with its own set of instructions.
It's working fine. However there is one problem and that is all the threads are clashing together. When they print out a message in the python shell they are blended together.

I have done some research in to it but from what I have found it is confusing the heck out of me. All i want to do is have the output of obj1, obj2 and obj3 own there own lines and not smashed together.

here is my current code

import _thread
class BaseClass(object):
def __init__(self, name):
self.name = name
_thread.start_new_thread( self.UpdateHandler,() )

def ClassType(self):
"""Returns a string of the childs type"""
pass

def UpdateHandler(self):
#this part handles when to call the update.
#it is allso needed so that it can be run in a thread.
while True:
self.Update()

def Update(self):
#This is a place holder.
#It stops classes that dont have a Update function crashing when called
pass

#---------------------------------------------------------------------------------
class ChildClassA(BaseClass):
def __init__(self, name):
super(ChildClassA, self).__init__(name)

def ClassType(self):
return 'ChildClassA'

def Update(self):
print(self.name, ": is doing stuff CLASS A")

#----------------------------------------------------------------------------------
class ChildClassB(BaseClass):
def __init__(self, name):
super(ChildClassB, self).__init__(name)

def Update(self):
print(self.name, "This is a completley diffeent action CLASS B")
self.Hi()

def ClassType(self):
return 'ChildClassB'

def Hi(self):
print("Hi")
#----------------------------------------------------------------------------------
class ChildClassC(BaseClass):
def __init__(self, name):
super(ChildClassC, self).__init__(name)

def Update(self):
print(self.name, "This is a completley diffeent action")

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

obj1 = ChildClassA('Obj1')
obj2 = ChildClassA('Obj2')
obj3 = ChildClassB('Obj3')

Answer

What you need is a semaphore, which is a multi-threaded lock object. https://en.wikipedia.org/wiki/Semaphore_(programming).

You sometimes see the same principle in kindergarten or pre-schools where to go to the toilet you need to take a necklace or another object to indicate the toilet is not occupied.

A semaphore object has two operations traditionally called P and V. The P operation requests the lock. If the lock is currently taken, the thread will wait until the lock becomes free. The V operation will free the lock, allowing another thread a chance to take the lock. P and V are abbreviations for the Dutch words "plaatsen" en "vrijgeven" ("put" and "release").

In python you can create a semaphore object by using the threading.Semaphore() or the _thread.request_lock() factory functions. The resulting objects have two methods: acquire (=P) and release (=V).

import _thread
class BaseClass(object):
    lock = _thread.request_lock()
    def __init__(self, name):
        self.name = name
        _thread.start_new_thread( self.UpdateHandler,() )

    def ClassType(self):
        """Returns a string of the childs type"""
        pass

    def UpdateHandler(self):
        #this part handles when to call the update.
        #it is allso needed so that it can be run in a thread.
        while True:
            self.lock.acquire()
            self.Update()
            self.lock.release()


    def Update(self):
        #This is a place holder.
        #It stops classes that dont have a Update function crashing   when called
        pass