用途:本技能面向需要编写下游 C 扩展的场景,使自定义类型能被放入 bocpy 的 Cown,经 @when 调度,或通过 send/receive 在 worker 子解释器之间传递。仅当类型包装原生 C 资源(大缓冲区、矩阵、GPU 句柄、文件描述符、FFI 指针等)且不希望每次跨解释器都复制或 pickle,并需要“同一时刻至多一个解释器可读写该资源”的隔离保证时才需要它。纯 Python、可 pickle 或可接受复制的类型不需要,Cown(my_obj) 已足够。
主要能力:采用 proto-Region 所有权模型,impl 上的单个原子 owner 字段标识当前可读写 payload 的解释器。生产者侧 XIData 回调将 owner 从 bocpy_interpid() 以 CAS 置为 BOCPY_NO_OWNER,消费者侧回调再从 BOCPY_NO_OWNER CAS 回 bocpy_interpid();任何数据访问器在读写前断言当前解释器拥有该 impl,否则抛 RuntimeError。它不包含嵌套区域、freeze、merge、借用跟踪。
使用方式:以模板 templates/c_abi_consumer/ 为起点,参考 src/bocpy/math.c 的 Matrix 实现。setup.py 用 bocpy.get_include() 与 bocpy.get_sources(),pyproject.toml 在构建与运行时都声明 bocpy,用 pip install --no-build-isolation 安装。头文件 #include <bocpy/bocpy.h> 须先于系统头,且仅支持 C。公开 ABI 包括 BOCPY_ABI、BOCPY_NO_OWNER、bocpy_interpid()、原子操作、thread_local、XIDATA* 系列与 XIDATA_REGISTERCLASS 等。实现要点:堆分配的 impl 含原子引用计数与 owner;用 PyType_FromModuleAndSpec 建堆类型并存入每模块状态与 thread_local 缓存;生产者回调用 XIDATA_GETDATA_FUNC 声明并做 CAS;消费者回调重建包装并在失败时回滚 owner;模块用多阶段初始化,在 Py_mod_exec 中注册类型并声明 Py_MOD_PER_INTERPRETER_GIL_SUPPORTED。
限制与硬性规则:所有调度 @when 的 Python 文件须顶层 import 该扩展,运行时的 importlib、import 或 pytest.importorskip 对转译器不可见;XIDATA_REGISTERCLASS 必须在 Py_mod_exec 而非 PyInit;生产者与消费者 CAS 必须成对;分配失败须回滚 owner;@when 内不得 send 该 proto-Region 资源本身,应发副本或摘要数据;不得依赖内部头文件;禁止 C++;须防止 Py_BUILD_CORE 泄漏。