python-3.x - Python:带线程的异步循环
问题描述
你能告诉我这是否是在自己的线程中构建多个独立异步循环的正确方法吗?
def init():
print("Initializing Async...")
global loop_heavy
loop_heavy = asyncio.new_event_loop()
start_loop(loop_heavy)
def start_loop(loop):
thread = threading.Thread(target=loop.run_forever)
thread.start()
def submit_heavy(task):
future = asyncio.run_coroutine_threadsafe(task, loop_heavy)
try:
future.result()
except Exception as e:
print(e)
def stop():
loop_heavy.call_soon_threadsafe(loop_heavy.stop)
async def heavy():
print("3. heavy start %s" % threading.current_thread().name)
await asyncio.sleep(3) # or await asyncio.sleep(3, loop=loop_heavy)
print("4. heavy done")
然后我正在测试它:
if __name__ == "__main__":
init()
print("1. submit heavy: %s" % threading.current_thread().name)
submit_heavy(heavy())
print("2. submit is done")
stop()
我期待看到1->3->2->4
,但实际上它是1->3->4->2
:
Initializing Async...
1. submit heavy: MainThread
3. heavy start Thread-1
4. heavy done
2. submit is done
我认为我在理解异步和线程方面错过了一些东西。
线程不同。为什么我要在里面MainThread
等到里面的工作Thread-1
完成?
解决方案
为什么我要在里面
MainThread
等到里面的工作Thread-1
完成?
好问题,你为什么?
一个可能的答案是,因为您实际上想阻塞当前线程,直到作业完成。这是将事件循环放在另一个线程中并使用run_coroutine_threadsafe
.
另一个可能的答案是,如果您不想要,则不必这样做。您可以简单地从返回submit_heavy()
的concurrent.futures.Future
对象返回run_coroutine_threadsafe
,然后让调用者自己等待结果(或检查是否准备好)。
最后,如果您的目标只是“在后台”运行常规函数(不阻塞当前线程),那么您可能根本不需要 asyncio。看看这个concurrent.futures
模块,它ThreadPoolExecutor
允许您轻松地将函数提交到线程池并让它在无人协助的情况下执行。
推荐阅读
- c# - 表单未在剃刀页面上加载
- python - SageMaker 中的 TensorFlow 电影镜头
- powershell - 无需安装即可替代 GroupPolicy 模块
- amazon-web-services - AWS::ApplicationAutoScaling::ScalableTarget 时区
- python - python mock test 实际和预期相等但失败
- javascript - 我可以使用 Options API 更新数据,但不能使用 Composition API
- java - 使用 // 在节点集中迭代后代时出现意外结果
- python - 消息嵌入未发送,可能出现其他错误
- azure - 我需要将多个域重定向到 azure 中的同一个静态 Web URL,以防整个站点关闭....任何人都可以建议
- php - 如何将两个 URL 参数放在一个 php 文件中?