2017-12-12 4 views
1

これは、プロジェクトでasyncioを使用する私の最初の試みです。クラスを初期化して実行し、その中のいくつかの関数を定期的にバックグラウンドで実行したいと思います。これらのバックグラウンドタスクを開始した後で、クラスのinitが戻るようにしたいので、同時に同期の作業を続けることができます。私が持っているものasyncioを使ってバックグラウンドでスレッドクラスの関数を実行する

class MyClass(threading.Thread): 
    def __init__(self, param): 
     self.stoprequest = threading.Event() 
     threading.Thread.__init__(self) 

     self.param = param 

     self.loop = asyncio.new_event_loop() 
     asyncio.set_event_loop(self.loop) 
     asyncio.ensure_future(self.periodic(), loop=self.loop) 

     print("Initialized") 

    async def periodic(self): 
     while True: 
      print("I'm here") 
      await asyncio.sleep(1) 

    def run(self): 
     # continue to do synchronous things 

私は当然、これは動作しません確信しています。また、私はinitでrun_until_complete()の "普通の" asyncio関数を使ってみましたが、もちろんinitはそれを返すことはありません。

asyncioこのクラスに属する関数はバックグラウンドで定期的に実行できますが、残りのクラス(run())は引き続き同期作業を行いますか?

答えて

2

ループを引数としてensure_futureに渡しても、このループは開始されません。コルーチンを強制的に起動させるには、run_until_completeまたはrun_foreverに電話する必要があります。他の方法はありません。

どのクラスの残りの部分(ラン()) 同期仕事をし続けている間、私は、このクラスのバックグラウンドで定期的に に属しasyncioの機能を実行できますか?

あなたがすることはできません。メインスレッドでイベントループと同期コードを同時に実行することはできません。 Loop starting - ループが停止するまでスレッドの実行フローをブロックします。これはちょうどasyncioの仕組みです。

asyncioをバックグラウンドで実行する場合は、別のスレッドで実行し、同期スレッドをメインスレッドで実行する必要があります。それを行う方法の例はhereです。

それあなたは今、メインスレッドでasyncioを実行するとrun_in_executor機能を使用して、バックグラウンドスレッドでコードをブロックし実行することですasyncio最も便利な方法と一緒に、スレッド内のコードをブロックし実行する必要があります。あなたはそれを行う例を見つけることができますhere

asyncioは、主に非同期プログラミングの利点を得るためにメインスレッド(他のスレッドなし)で使用されていると言うことが重要です。 2番目のスレッドが必要ですか?そうでない場合はthis answerを読んで、なぜasyncioが使用されているのかをご覧ください。

関連する問題