我正在編寫一個應用程序,用於偵聽聲音事件(使用傳入的Open Sound Control消息),然後基於這些事件暫停或恢復程序執行。我的結構大部分時間工作,但總是在主循環中爆炸,所以我猜這是一個線程問題。下面是我在談論的一個通用的,簡化的版本:理想的線程結構問題(涉及多線程通信)
import time, threading
class Loop():
aborted = False
def __init__(self):
message = threading.Thread(target=self.message, args=((0),))
message.start()
loop = threading.Thread(target=self.loop)
loop.start()
def message(self,val):
if val > 1:
if not self.aborted:
self.aborted = True
# do some socket communication
else:
self.aborted = False
# do some socket communication
def loop(self):
cnt = 0
while True:
print cnt
if self.aborted:
while self.aborted:
print "waiting"
time.sleep(.1);
cnt += 1
class FakeListener():
def __init__(self,loop):
self.loop = loop
listener = threading.Thread(target=self.listener)
listener.start()
def listener(self):
while True:
loop.message(2)
time.sleep(1)
if __name__ == '__main__':
loop = Loop()
#fake listener standing in for the real OSC event listener
listener = FakeListener(loop)
當然,這個簡單的代碼似乎工作的偉大,所以這顯然不能完全說明我真正的代碼,但你的想法。這裏沒有包含的事實是,在每個循環中暫停和恢復(通過設置aborted = True/False)會導致某些套接字通信,這也涉及到線程。
在我的代碼中經常發生的事情是,主循環並不總是在聲音事件發生後停止。它可以用於很多事件,但最終它不會回答。
有關如何在線程之間構建這種通信的任何建議?
更新:
好吧,我想我已經明白了。這是一個似乎可行的修改。有一個監聽器線程可以定期將值放入Queue對象中。有一個檢查器線程會不斷檢查隊列以查找值,一旦它看到它將布爾值設置爲其相反的狀態。該布爾值控制循環線程是繼續還是等待。
雖然我並不完全確定q.task_done()函數在做什麼。
import time, threading
import Queue
q = Queue.Queue(maxsize = 0)
class Loop():
aborted = False
def __init__(self):
checker = threading.Thread(target=self.checker)
checker.setDaemon(True)
checker.start()
loop = threading.Thread(target=self.loop)
loop.start()
def checker(self):
while True:
if q.get() == 2:
q.task_done()
if not self.aborted:
self.aborted = True
else:
self.aborted = False
def loop(self):
cnt = 0
while cnt < 40:
if self.aborted:
while self.aborted:
print "waiting"
time.sleep(.1)
print cnt
cnt += 1
time.sleep(.1)
class fakeListener():
def __init__(self):
listener = threading.Thread(target=self.listener)
listener.setDaemon(True)
listener.start()
def listener(self):
while True:
q.put(2)
time.sleep(1)
if __name__ == '__main__':
#fake listener standing in for the real OSC event listener
listener = fakeListener()
loop = Loop()
這是您的示例重寫爲使用多處理http://codepad.org/IRz04lkH – jfs 2010-11-06 10:10:02
多線程庫相比線程有什麼好處?我通常使用i5在Mac上運行,因此有多個內核可以使用。但是如果它在沒有多核的機器上運行,它是否默認爲典型的線程實現? – mix 2010-11-06 20:49:28
對於微不足道的例子,這取決於你的真實程序的功能。 Python擁有GIL,它可以訪問解釋器的大部分內容。 Mindblowing Python GIL http://blip.tv/file/2232410 – jfs 2010-11-07 07:56:54