2017-08-12 21 views
0

タイトルは申し訳ありませんが、私が1つの文章で何をしようとしているのかを明確に説明していません。基本的に私が持っている各オブジェクトは一度に1つ作成するとブロックしないほど速いですが、もし私が十数百を持っていれば、それはメインループをブロックします。私はオブジェクトを読み込むときに発生する吃音の量を減らす方法を見つけようとしています。基本的に私が持っているアプリケーションはすべてのフレームをレンダリングしなければならず、フレームより長いものがあれば、アプリケーションはやわらかく見えるようになります。ブロックせずにPython Twisted非同期スケジューリング

主な問題は、オブジェクトを作成するときに、jsonファイルからデータを検索してインポートすることです。現在、各jsonファイル自体はかなり速く(0.006秒)、フレームの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

試行された反応器のコールター(0.1、self.load())? –

+0

同じ結果を試してみました。 – Charlie

+0

申し訳ありませんが、今ここに遅れていて、今は何も役に立たないとは思いません...私は通常、メインプログラムを妨げたくないものをサブプロセスに入れます。あなたはそれについて考えましたか? –

答えて

0

基本的にはfor i in xrange(300)がメインリアクタをブロックしています。 load_objectsファンクションで小さな休憩をとり、原子炉/イベントループに制御を戻して、他のタスクを実行できるようにする簡単な方法があります。

@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.If上で行う 'self.load()'のためにブロックします。 'self.load'を削除すると即座にロードされます。私がしたいことは、すべてのJsonObjectをロードすることです(それ自体がinit上のload関数なしで高速です)。しかし、それぞれがself.loadへの呼び出しをスケジューリングしているので、ブロックされません。 – Charlie

+0

これは、この回答の役割です。それはまた、協力することができるものです。 cooperate()との相違点は、いくつかの数字をハードコーディングするのではなく、タイムベースの仕事チャンクを行うことです(あまりにも多くの場合があります - あなたに吃音を与えるか、少なすぎると処理時間が長くなります)。 –

+0

また、deferToThreadを正しく使用すると正常に動作するはずです。deferToThreadを使用するコードを投稿していないので、間違ったことを言うのは難しいです。 –

関連する問題