news 2026/8/30 10:37:44

Monty异步编程完全指南:async宿主函数、await与asyncio.gather并发执行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Monty异步编程完全指南:async宿主函数、await与asyncio.gather并发执行

Monty异步编程完全指南:async宿主函数、await与asyncio.gather并发执行

【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty

Monty 是一个用 Rust 编写的极简、安全 Python 解释器,专为 AI 生成代码而设计。它的异步编程模型让沙箱代码可以安全地并发调用宿主函数:通过AsyncMontyawaitasyncio.gather,你可以把网络请求、数据库查询等耗时操作放到宿主机上并行执行,而不需要容器或线程。

为什么 Monty 需要异步模型

传统沙箱靠容器隔离,启动慢、资源重。Monty 走的是另一条路:沙箱不直接碰外部世界,任何外部交互都必须通过开发者显式提供的宿主函数(Host Function)完成。

对于耗时较长的操作(比如fetch一个网页),同步阻塞会白白占用整个执行流。Monty 的解法是:

  • 沙箱内部的async def/await语法与 Python 一致
  • 沙箱里没有事件循环,宿主就是事件循环(the host is the loop)
  • asyncio.gather让多个宿主调用真正并发运行

这个设计保证了:既拿到并发性能,又保持零信任隔离。🔒

快速上手:AsyncMonty + 异步宿主函数

只需三步:

  1. 使用AsyncMonty代替同步的Monty
  2. external_lookup中传入协程函数async def定义的宿主函数)
  3. 沙箱代码用awaitgather调用它们
from pydantic_monty import AsyncMonty async def fetch(url: str) -> str: return f'contents of {url}' code = "await fetch('https://example.com')" async with AsyncMonty() as pool: async with pool.checkout() as session: result = await session.feed_run(code, external_lookup={'fetch': fetch})

⚠️ 注意:同步版Monty不能驱动协程宿主函数,必须用AsyncMonty,或改用快照机制手动驱动挂起。

更完整的入门示例见 docs/quickstart/python.md。

asyncio.gather:让多个宿主调用真正并发

asyncio.gather是沙箱内的并发核心。它接收多个可等待对象,同时发起宿主调用并返回结果列表(顺序与参数一致,而非完成顺序)。

import asyncio results = await asyncio.gather(fetch('a'), fetch('b'))

几个关键行为:

场景Monty 的行为
多个宿主调用全部并发执行,结果按参数顺序返回
空参数gather()返回[]
传入非可等待对象TypeError
支持*args解包✅ 列表、元组均可
同一协程/future 传入两次自动去重,函数体只执行一次
已完成/失败的 gather 再次 await返回缓存结果,或重复抛出缓存异常

gather的实现细节(任务状态机、结果槽位、去重逻辑)可以在 crates/monty/src/asyncio.rs 中看到,行为验证用例在 crates/monty/test_cases/async__gather_all.py。

并发模型:协作者式调度,没有抢占

理解 Monty 异步的关键一句话:并发是协作式、宿主驱动的。

  • gather会在所有分支都阻塞在外部调用时,把挂起的调用交给宿主
  • 宿主返回结果后,沙箱再恢复执行
  • 没有抢占、没有线程、沙箱内没有调度器

这意味着两点实际影响:

  1. 协程是一次性的(single-shot):同一个协程对象 await 第二次会抛RuntimeError。需要复用结果时,请保存结果而不是协程本身。
  2. 宿主回调内部若写了阻塞代码,会阻塞你自己的事件循环——AsyncMonty移离事件循环的是 worker I/O,而不是你的回调。

asyncio 模块的边界:只有 run 和 gather

沙箱里的asyncio模块刻意做得很小,只暴露两个函数:

  • asyncio.run(coro)—— 运行协程直到结束
  • asyncio.gather(*awaitables)—— 并发执行并收集结果(不支持任何关键字参数)

create_tasksleepwaitQueueLock等均未实现(访问会抛AttributeError);async forasync with和异步推导式则在解析期直接拒绝。完整的差异清单见 limitations/asyncio.md。

另外两个值得知道的与 CPython 的差异:

  • 未 await 的 gather 不会启动子任务asyncio.gather(boom())若丢弃结果,Monty 里什么代码都不会执行
  • 失败的 gather 的兄弟任务推进受限:它们只会在宿主结果到达或其他任务挂起时恢复,因此某些边界场景的输出顺序与 CPython 不同

进阶:手动驱动挂起(快照)

如果不想让feed_run自动应答所有挂起,可以用feed_start拿到每一个挂起点(快照),记录、限流、审批,甚至序列化到数据库明天再恢复:

snapshot = session.feed_start('fetch(url)', inputs={'url': 'https://example.com'}) result = snapshot.resume({'return_value': 'page contents'})

当沙箱内所有任务都阻塞在宿主 future 上时,会得到FutureSnapshot,可按call_id批量提交结果。详见 docs/snapshots.md。

相关文件速查

内容路径
宿主函数完整指南docs/host-functions.md
asyncio 限制与差异limitations/asyncio.md
核心异步类型(协程/Future/Gather)crates/monty/src/asyncio.rs
基础 await 用例crates/monty/test_cases/async__basic.py
gather 并发用例crates/monty/test_cases/async__gather_all.py
异步宿主调用用例crates/monty/test_cases/async__ext_call.py
Python 快速上手docs/quickstart/python.md

小结

Monty 的异步编程为「AI 写代码、宿主供工具」的场景提供了轻量又安全的并发方案:

  1. AsyncMonty开启异步池,宿主函数写成async def
  2. 沙箱内用await单点调用,用asyncio.gather批量并发
  3. 记住沙箱无事件循环——宿主即循环,并发性能取决于你的宿主实现
  4. 需要暂停/恢复/审计时,用快照机制接管每一次挂起

掌握这四点,你就能在微秒级启动的沙箱里,安全地跑起 AI 生成的并发 Python 代码了。🚀

【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 10:36:17

Vibe Coding实战:Codex与Claude Code的工程化落地与踩坑指南

Vibe Coding听起来像是“随便聊天就能写代码”,但我在项目里见过的真实情况,往往没有这么性感。有人第一天用Claude Code生成了一整套订单导出脚本,觉得已经掌握了“未来”;第二天脚本接入生产数据,输出表格全乱了&…

作者头像 李华
网站建设 2026/8/30 10:33:07

Real-Time-Voice-Cloning:5 秒克隆任意声音的实时语音克隆方案

Real-Time-Voice-Cloning:5 秒克隆任意声音的实时语音克隆方案 【免费下载链接】Real-Time-Voice-Cloning Clone a voice in 5 seconds to generate arbitrary speech in real-time 项目地址: https://gitcode.com/GitHub_Trending/re/Real-Time-Voice-Cloning …

作者头像 李华
网站建设 2026/8/30 10:31:29

嵌入式开发环境的复现方法

嵌入式开发环境的复现方法嵌入式问题常常有很强的环境依赖:同一份代码在开发板上失败,在电脑上却正常;某台设备偶发重启,换一块板子又无法重现。原因可能藏在系统镜像、内核驱动、外设连接、启动参数、时钟或实际负载里。仅把应用…

作者头像 李华
网站建设 2026/8/30 10:28:55

AI辅助基金申请书写作:工程化提分与同质化风险应对

最近这一年,关于大模型辅助科研写作的讨论非常多。真正让我停下来想了一想的,是这样一条结论:使用 AI 辅助撰写的基金申请书,在评审环节更容易拿到高分、中标概率更高;但与此同时,AI 加工后的文本在语言风格…

作者头像 李华