Asyncioループを呼び出すスレッドがありますが、これにより上記の例外が発生します。
RuntimeError: There is no current event loop in thread 'Thread-1'.
この質問: RuntimeError:async + apschedulerのスレッドには現在のイベントループがありません は同じ問題に遭遇しましたが、私が持っていないスケジューラを参照していました。
私のコードは次のとおりです:
def worker(ws):
l1 = asyncio.get_event_loop()
l1.run_until_complete(ws.start())
l2 = asyncio.get_event_loop()
l2.run_forever()
if __name__ == '__main__':
ws = Server()
p = threading.Thread(target=worker,args=(ws,))
p.start()
while True:
try:
#...do sth
except KeyboardInterrupt:
p.join()
exit()
新しいスレッドにはイベントループがないため、明示的に渡して設定する必要があります。
_def worker(ws, loop):
asyncio.set_event_loop(loop)
loop.run_until_complete(ws.start())
if __name__ == '__main__':
ws = Server()
loop = asyncio.new_event_loop()
p = threading.Thread(target=worker, args=(ws, loop,))
p.start()
_
また、p.join()
はサーバーを停止しないため、スクリプトを正しく終了せず、ループが継続して実行され、おそらくスレッドがハングアップします。スレッドに参加する前にloop.call_soon_threadsafe(ws.shutdown)
のようなsmthを呼び出す必要があります。理想的にはサーバーの正常なシャットダウンを待機します。
Python 3.7.3を使用するWindowsでは、スレッドに直接イベントループを作成する代わりに、
しなければならない:
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
そうしないと、問題が解決しません。
スレッドでボケサーバーを実行すると、この問題が発生しました。 server = Server({'/':app}、port = 0)を作成しようとすると、このエラーが発生します。トルネードのドキュメントから、次のことがわかりました...
Class tornado.platform.asyncio.AnyThreadEventLoopPolicy[source]
任意のスレッドでループの作成を許可するイベントループポリシー。デフォルトのasyncioイベントループポリシーでは、メインスレッドでのみイベントループが自動的に作成されます。他のスレッドはイベントループを明示的に作成する必要があります。そうしないと、asyncio.get_event_loop(したがってIOLoop.current)が失敗します。このポリシーをインストールすると、5.0(またはPython 2)の5.0)より前のTornadoバージョンの動作に一致するイベントループがすべてのスレッドで自動的に作成されます。
使用法:
asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
http://www.tornadoweb.org/en/stable/asyncio.html#tornado.platform.asyncio.AnyThreadEventLoopPolicy