2015-02-17 97 views
0

我有一個運行彈球機的Python應用程序。它需要以相當一致的循環速度運行以進行彈球類型的操作,但是我還需要能夠在整個遊戲的各個點上加載圖像和聲音。我沒有足夠的內存來預加載整個遊戲所需的所有聲音文件,因此我希望在主遊戲循環繼續時使用其他線程(或多個線程)在後臺加載它們。在長時間運行的應用程序中使用臨時線程?

使用Python的threading模塊很容易,因爲使用Queue.Queue來維護需要加載的資產列表。我的問題是,如果資產加載器線程始終運行,是否「OK」(缺少更好的單詞),或者我是否應該在需要時創建線程,然後在完成時讓它結束。在我的情況下,彈球機和我的Python應用程序一次將運行數小時(或數天)。

所有Python線程的示例我發現它們傾向於應用程序執行某些操作,然後結束,而不是爲長時間運行的應用程序創建(可能)臨時線程。

在我來說,我想我有兩個選擇:

選項1,其中裝載機線程運行永遠:

self.loader_queue = Queue.Queue 

def loader_thread(self): 
    while True: 
     do_my_work(self.loader_queue.get()) 

選項2,其中裝載機線頭當隊列爲空:

def loader_thread(self): 
    while not self.loader_queue.empty(): 
     do_my_work(self.loader_queue.get()) 

很顯然,我已經留下了一些東西出來。有些try:塊和創建選項2線程的方法,但是我覺得這些片段解釋我兩個選項。

我真正的問題是,使用選項1,是「壞」,因爲那麼我就浪費了一半的Python執行週期,而加載程序線程只是旋轉並且對於99.99%的排隊時間沒有做任何事情空?

或者是這種情況下,我應該使用第一個選項,但使用self.loader_queue.get(block=True)?我假設如果我的加載程序線程在等待隊列中的項目時只是阻塞,那麼這是一種有效的等待類型,我不會浪費一堆循環嗎?

謝謝! 布賴恩

回答

1

Queue.get默認爲阻止,這是你需要的東西:

卸下並從隊列中返回一個項目。如果可選參數塊爲true並且超時時間爲無(默認爲),則根據需要進行阻止,直到項目可用。如果超時是一個正數,它將最多阻塞秒數,並在該時間內沒有可用項目時引發空例外。否則(block爲false),如果一個立即可用,則返回一個項目,否則引發Empty異常(在這種情況下超時被忽略)。

這種方式while循環只對隊列中的每個項目運行一次,並在隊列爲空時被阻塞。

您可以通過在while循環中執行一些可見的事情(如打印輸出)來親自測試它。

如果您正在等待項目,則選項1很好,因爲選項2可能會在您獲取它們之前終止(如果加載速度足夠快)。

該線程可能沒有佔用足夠的資源被視爲優化候選人。而且,因爲當它不應該運行時你阻止了它,選項1似乎是要走的路。

相關問題