[英]Why get_event_loop Cannot Be Used With run_in_executor
Could anyone tell why the code below谁能告诉为什么下面的代码
import asyncio
import time
from concurrent.futures import ThreadPoolExecutor
ASYNC_INTERVAL = 0.1
def plain_hello_world(name):
s = "Hello world "+str(name)
print(s)
return s
def plain_loop(name, t):
start_time = time.time()
prev_time = start_time
while (time.time() - start_time < t):
if time.time() - prev_time > ASYNC_INTERVAL:
prev_time = time.time()
plain_hello_world(name)
def task1():
loop = asyncio.get_event_loop()
task = loop.run_in_executor(None, plain_loop, "func", 1)
loop.run_until_complete(task)
def task2():
loop = asyncio.get_event_loop()
task = loop.run_in_executor(None, task1)
loop.run_until_complete(task)
if __name__ == "__main__":
task2()
gets error below:得到以下错误:
Traceback (most recent call last):
File "asyncio_practice4.py", line 28, in <module>
task2()
File "asyncio_practice4.py", line 25, in task2
loop.run_until_complete(task)
File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
return future.result()
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "asyncio_practice4.py", line 18, in task1
loop = asyncio.get_event_loop()
File "/usr/lib/python3.6/asyncio/events.py", line 694, in get_event_loop
return get_event_loop_policy().get_event_loop()
File "/usr/lib/python3.6/asyncio/events.py", line 602, in get_event_loop
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'ThreadPoolExecutor-0_0'.
Question:题:
I do not understand why such error occurs.我不明白为什么会发生这样的错误。
Running task1()
only is fine, but along with one another run_in_executor()
it says no current evet loop.运行task1()
仅仅是罚款,但有一个沿另一run_in_executor()
它说没有电流EVET环。 (But I think it should, I did not create a new thread) (但我认为应该,我没有创建新线程)
Does anyone know what is going on?有谁知道发生了什么?
And how to fix it assuming we can only work on task2()
?假设我们只能在task2()
上工作,如何解决它?
Note:笔记:
The reason to call 2 run_in_executor()
is because code above is mimicking integrating a 3rd lib into asyncio code.调用 2 run_in_executor()
的原因是因为上面的代码正在模仿将第三个库集成到 asyncio 代码中。
plain_hello_world()
, plain_loop()
, and task1()
are codes in lib, which I cannot modify. plain_hello_world()
plain_loop()
和task1()
是码的lib,这是我不能修改。
Assuming task1()
runs for 100s and I do not want to wait for it, so I try to run it in executor as how other plain functions work with asyncio.假设task1()
运行了 100 秒并且我不想等待它,所以我尝试在 executor 中运行它,就像其他普通函数如何与 asyncio 一起工作一样。
Edit: Based on the answer, here is the revision that works:编辑:根据答案,这是有效的修订:
def task2():
loop = asyncio.get_event_loop()
def wrapper():
asyncio.set_event_loop(asyncio.new_event_loop())
task1()
task = loop.run_in_executor(None, wrapper)
loop.run_until_complete(task)
Though I am not sure how "correct" or good it is.虽然我不确定它有多“正确”或好。
I do not understand why such error occurs.我不明白为什么会发生这样的错误。
It occurs because task1
assumes that it will run in either the main thread (where get_event_loop()
creates an event loop on-demand) or in a thread where set_event_loop
was previously called to set up an event loop.这是因为task1
假设它将在主线程中运行(其中get_event_loop()
按需创建事件循环)或在先前调用set_event_loop
以设置事件循环的线程中set_event_loop
。 Since run_in_executor
invokes its function in a thread other than the main thread, and your code doesn't call set_event_loop()
before invoking it, you get the error.由于run_in_executor
在主线程以外的线程中调用其函数,并且您的代码在调用它之前没有调用set_event_loop()
,因此您会收到错误消息。
Assuming task1() runs for 100s and I do not want to wait for it, so I try to run it in executor as how other plain functions work with asyncio.假设 task1() 运行了 100 秒并且我不想等待它,所以我尝试在 executor 中运行它,就像其他普通函数如何与 asyncio 一起工作一样。
Running a sync function and not waiting for it is not something you do with asyncio, it's a job for regular threads.运行同步函数而不等待它不是你用 asyncio 做的事情,它是常规线程的工作。 For example:例如:
def task1_bg():
def work():
asyncio.set_event_loop(asyncio.new_event_loop())
task1()
threading.Thread(target=work).start()
if __name__ == '__main__':
task1_bg()
# do something else...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.