2016-08-27 93 views
0

我有一個基類,有一個名爲Update的空方法。 這個Update方法被X個不同的子類繼承 基類每30個tick就調用一次Update方法一次(現在不是這樣,它現在只是在一個循環中做,但我打算每30 ) 每個子類都有自己的方法Update及其自己的指令集。 它工作正常。但是有一個問題,那就是所有的線程都在一起衝突。當他們在python shell中打印出一條消息時,它們被混合在一起。Python線程同步

我已經做了一些研究,但從我發現它是混淆了我。我想要做的就是讓obj1,obj2和obj3的輸出擁有自己的行,而不是砸在一起。

這裏是我當前的代碼

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

回答

1

你需要的是一個semaphore,這是一個多線程鎖定對象。 https://en.wikipedia.org/wiki/Semaphore_(programming)

你有時在幼兒園或學前班看到同樣的原則,在哪裏上廁所你需要拿項鍊或其他物品來表明廁所沒有被佔用。

一個信號量對象有兩個傳統上稱爲PV的操作。 P操作請求鎖定。如果當前正在進行鎖定,則線程將等待鎖定變爲空閒狀態。 V操作將釋放該鎖,從而允許另一個線程有機會取鎖。 PV是荷蘭語「plaatsen」和「vrijgeven」(「put」和「release」)的縮寫。

在python中,您可以使用threading.Semaphore()_thread.request_lock()工廠函數創建信號量對象。生成的對象有兩種方法:acquire(= P)和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 
+0

好了,現在讓很多降神和聽起來像在exsatley什麼,我lookign這麼即時假設它是** **的東西像 '而真: threading.Semaphore.acquire( ) self.Update() threading.Semaphore.release()' 但是,這是線程模塊的一部分。如同_thread模塊一樣。並且從我研究過的線程模塊的網站來看,首先讓我感到困惑的是。這就是爲什麼我使用舊的_thread模塊。 – skyzzle

+0

如果你想保留'_thread',你可以使用'_thread.allocate_lock()'。得到的鎖對象也有'acquire'和'release'方法。 –