python-3.x - Python asyncio:在没有创建任务的情况下启动循环
问题描述
有人可以解释一下,如果我之前没有添加任何任务就开始循环,为什么我不能执行我的任务?(Python 3.7)
import asyncio
import threading
def run_forever(loop):
loop.run_forever()
async def f(x):
print("%s executed" % x)
# init is called first
def init():
print("init started")
loop = asyncio.new_event_loop()
# loop.create_task(f("a1")) # <--- first commented task
thread = threading.Thread(target=run_forever, args=(loop,))
thread.start()
loop.create_task(f("a2")) # <--- this is not being executed
print("init finished")
# loop.create_task(f("a1"))
如果我对执行发表评论是:
init started
init finished
未注释的执行是:
init started
init finished
a1 executed
a2 executed
为什么这样?我想创建一个循环并在将来添加任务。
解决方案
除非另有明确说明,否则 asyncio API不是线程安全的。这意味着loop.create_task()
从运行事件循环的线程以外的线程调用将无法与循环正确同步。
要将任务从外部线程提交到事件循环,您需要调用asyncio.run_coroutine_threadsafe
:
asyncio.run_coroutine_threadsafe(f("a2"), loop)
这将唤醒循环以提醒它有新任务到达,它还会返回一个concurrent.futures.Future
您可以用来获取协程结果的循环。
推荐阅读
- sql - SQL Server中计算余弦相似度的优化方法
- git - 如何使用 Git 将文件添加到 master 分支而不自动将其添加到其他分支
- python-3.x - python中的独特功能
- javascript - React-navigation 切换主题切换
- excel - Excel VBA 创建新的 PivotCache 并连接多个数据透视表
- snowflake-cloud-data-platform - Snowflake 与 Azure Dev Ops 的集成
- c - 为什么 ucontext_t 比 sigjmp_buf 大这么多?
- java - Java - 从播放时间中减去暂停时间
- javascript - 仅当我在反应选择中使用 onChange 时,如何调用 fetch?
- regex - 正则表达式获取 2 个单词之间的所有内容