繁体   English   中英

为什么 get_event_loop 不能与 run_in_executor 一起使用

[英]Why get_event_loop Cannot Be Used With run_in_executor

谁能告诉为什么下面的代码

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()

得到以下错误:

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'.

题:

我不明白为什么会发生这样的错误。

运行task1()仅仅是罚款,但有一个沿另一run_in_executor()它说没有电流EVET环。 (但我认为应该,我没有创建新线程)

有谁知道发生了什么?

假设我们只能在task2()上工作,如何解决它?

笔记:

调用 2 run_in_executor()的原因是因为上面的代码正在模仿将第三个库集成到 asyncio 代码中。

plain_hello_world() plain_loop()task1()是码的lib,这是我不能修改。

假设task1()运行了 100 秒并且我不想等待它,所以我尝试在 executor 中运行它,就像其他普通函数如何与 asyncio 一起工作一样。

编辑:根据答案,这是有效的修订:

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)

虽然我不确定它有多“正确”或好。

我不明白为什么会发生这样的错误。

这是因为task1假设它将在主线程中运行(其中get_event_loop()按需创建事件循环)或在先前调用set_event_loop以设置事件循环的线程中set_event_loop 由于run_in_executor在主线程以外的线程中调用其函数,并且您的代码在调用它之前没有调用set_event_loop() ,因此您会收到错误消息。

假设 task1() 运行了 100 秒并且我不想等待它,所以我尝试在 executor 中运行它,就像其他普通函数如何与 asyncio 一起工作一样。

运行同步函数而不等待它不是你用 asyncio 做的事情,它是常规线程的工作。 例如:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM