2017-08-12 64 views
0

對不起,我不知道如何描述我想要做的單個句子。基本上我每個對象都有足夠快的速度,一次創建1個就不會阻塞,但是如果我有一個或幾百個,那麼它會阻止主循環。我正試圖找到一種方法來減少加載對象時發生的口吃量。從本質上講,我的應用程序必須渲染每一幀,並且如果任何東西長於一幀,應用程序開始出現抖動。Python無阻塞的扭曲異步調度

主要問題是,當我創建對象時,他們必須從json文件中查找數據並導入它。現在每個json文件本身都很快(0.006s),比一幀的1/60快。但是,當計數器開始變爲x * 0.006時,就成了問題。

有趣的是,如果我使用類似deferToThread的東西它仍然阻止主循環。這是我想要做的。我希望即時提供對象,因爲立即完成它們非常重要。然而,實際的json加載並不重要,我想以某種方式安排它,讓其他人開始「填充」,以便在可用時進行發言。它們的可用順序也是不必要的。

from twisted.internet import reactor, defer 
from profilehooks import profile 
import json 

objects = [] 

def print_test(text): 
    print text 

class JsonObject(object): 
    def __init__(self, i): 
     self.i = i 
     self.json_data = None 
     self.load() # <load data slowly somehow?> 
     # Threads not working either? 
     #d = threads.deferToThread(self.load) 
     #d.addCallback(self.set_json_data) 

    def load(self): 
     with open("{0}.json".format(str(self.i).zfill(3))) as f: 
      self.json_data = json.load(f) 
     #return self.json_data 


    def set_json_data(self, data): 
     print "GOT DATA", self.i 

def load_objects(): 
    for i in xrange(300): 
     objects.append(JsonObject(i)) 

    print "LOADED ALL OBJECTS" 

reactor.callLater(0, load_objects) 
reactor.callLater(0.5, print_test, "test for blocking") 
reactor.run() 
+0

嘗試reactor.callLater(0.1,self.load())? –

+0

試過,結果也一樣。 – Charlie

+0

對不起,現在在這裏已經很晚了,現在我無法想到任何有用的東西......我通常會把一些我不想幹涉主程序的東西放到子程序中。你有想過嗎? –

回答

0

基本上for i in xrange(300)阻止你的主反應堆。這是一個簡單的方法,可以在你的load_objects函數中稍微休息一下,並將控制返回到reactor/event循環,以便完成其他任務。

@defer.inlineCallbacks 
def load_objects(): 
    for i in xrange(300): 
     objects.append(JsonObject(i)) 

     if i % 100 == 0: 
      yield # take a break and let reactor do other tasks 

     print("LOADED ALL OBJECTS") 

另外還有的cooperate功能,做類似的事情,但我總是發現inlineCallbacks更加直觀。

+0

對不起,我不清楚,是的,我意識到我提供的例子會因爲對象的數量而被阻塞。它會阻止它,因爲對象在init上執行self.load()。如果我刪除'self.load',它會立即加載。我想要做的就是加載所有的JsonObject(因爲它們本身就是快速的,沒有初始化時的加載函數),但是它擁有它,所以每個人都安排了一個對self.load的調用,這個調用將被「分散」它不會阻止。 – Charlie

+0

這就是這個答案。這也是合作()會做的。與合作()(這使得它更好)的區別在於它可以完成基於時間的工作塊,而不是對某些數字進行硬編碼(這可能太多了 - 會導致你口吃 - 或者太少 - 使得這個過程需要更長的時間。) –

+0

另外,deferToThread應該可以正常工作,但是你沒有發佈任何使用deferToThread的代碼,所以很難說你可能做了什麼錯誤。 –