Может кто-нибудь сказать, почему код ниже
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()
он говорит, что в настоящее время нет l oop. (Но я думаю, что должно, я не создал новую тему)
Кто-нибудь знает, что происходит?
И как это исправить, предполагая, что мы можем работать только на task2()
?
Примечание:
Причина вызова 2 run_in_executor()
состоит в том, что приведенный выше код имитирует интеграцию третьей библиотеки в асинхронный код.
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)
Хотя я не уверен насколько это "правильно" или хорошо.