执行契约
- 协程固定归属于创建它的原生线程,
Resume、活跃对象的销毁和调度操作只能在该线程执行。 - Windows 使用
CreateFiberEx的可增长栈,仅保留StackSize指定的虚拟地址空间,并从较小提交量开始按需增长。 - POSIX 原生后端使用匿名映射和不可访问保护页;可写映射由操作系统按首次访问提交物理页面。
- 每个协程拥有独立的临时内存 arena、结构化错误上下文和取消令牌。
xrtCoCancelToken返回增加引用后的取消令牌,调用方使用完毕后必须调用xrtCancelDestroy。- 取消是协作式的。
xrtCoYield在恢复后返回XWAIT_CANCELLED,未启动的已取消协程不会执行用户过程。 - 取消请求与终态正交:处理请求后正常返回仍是
XCORO_TERM_RETURNED;调用xrtCoConfirmCancel后返回才是XCORO_TERM_CANCELLED。 - 用户过程正常返回时若仍留有未处理错误,终态为
XCORO_TERM_ERROR;显式确认取消优先于残留错误。
生命周期
xrtCoCreate 创建 XCORO_READY 对象。xrtCoResume 运行到下一次 xrtCoYield 或过程返回。只有未启动的 READY 对象和 DONE 对象可以由 xrtCoDestroy 销毁;拒绝销毁活跃栈可避免跳过清理过程或留下悬空上下文。
外部创建的线程在最后一个协程结束后可调用 xrtCoThreadDetach 释放惰性线程运行时。xrtThreadCreate 创建的线程会在退出时自动执行该步骤;仍有挂起协程时 detach 会失败。
xrtCoStopping 用于查询当前协程是否收到取消请求。等待函数返回 XWAIT_CANCELLED 后,用户代码可以清理并正常返回结果;确实要把本次执行记为取消时调用 xrtCoConfirmCancel。没有取消请求、普通线程路径或清理栈中调用确认函数都会失败并设置 XERR_STATE。
平台后端
| 平台 | 后端 | 栈策略 |
|---|---|---|
| Windows x86/x64/ARM64 | Fiber | CreateFiberEx 保留上限、按需提交 |
| POSIX x86-64 | 原生汇编 | mmap 惰性页面和保护页 |
| POSIX ARM64 | AAPCS64 原生汇编 | mmap 惰性页面和保护页 |
| POSIX RISC-V 64 | LP64 原生汇编,按浮点 ABI 保存 | mmap 惰性页面和保护页 |
| POSIX LoongArch64 | LP64 原生汇编,按浮点 ABI 保存 | mmap 惰性页面和保护页 |
所有原生后端保存 ABI 规定的整数和浮点非易失寄存器。当前发布构建必须在对应目标上执行上下文、深栈和浮点寄存器测试;仅在其他平台编译成功不能替代运行验证。
POSIX 手工栈切换在 AddressSanitizer 构建中使用官方 fiber switch 接口登记栈范围和 fake stack,协程永久结束时主动释放其 fake stack;MemorySanitizer 构建使用对应的 fiber switch 接口登记新旧栈边界;ThreadSanitizer 构建为每个协程维护独立 fiber 身份,避免把不同协程的访问历史混为同一执行上下文。Sanitizer 发布门禁必须使用包含对应运行时的插桩工具链实际执行,只有编译或链接结果不能替代运行验证。Linux x86-64 在启用 CET 时同时支持 IBT 和 shadow stack:内部恢复点包含 ENDBR64,每个协程按需映射独立 shadow stack 并随协程销毁。其他 x86-64 系统若要求 SHSTK,编译阶段会明确拒绝,不能静默生成不完整上下文。
清理栈
清理栈提供两层 API:
xrtCoDefer是常用路径,由协程分配并管理节点,过程返回后仍可可靠执行。xrtCoCleanupPush是无分配路径,节点必须先使用XRT_CO_CLEANUP_INIT或全零初始化,且存储期必须覆盖协程终态;不能把未弹出的节点放在协程过程的自动局部变量中。
xrtCoCleanupPop 可以弹出任一种节点,并可选择立即执行。所有仍在栈上的清理过程按后进先出顺序执行,清理过程中禁止让出协程。
调度器
XRT_FEATURE_COROUTINE_SCHEDULER 在核心之上增加单线程调度器。调度器、执行队列、timer heap 和 join 链只由所属线程修改;跨线程入口只把工作放入互斥保护的 FIFO 队列,再由所属线程修改执行结构。
xrtCoSpawn返回保留句柄。协程完成后仍可读取Term、Result和Error,最后由xrtCoDestroy或调度器销毁。xrtCoGo创建分离协程,完成后自动回收,适合不需要结果的后台过程。xrtCoSchedPost从任意线程投递借用数据的短过程;xrtCoSchedPostOwned在受理后接管数据,并在过程返回后恰好析构一次。失败时 Owned 数据仍归调用方。xrtCoPark、ParkFor、ParkUntil区分OK、TIMEOUT和CANCELLED;提前 wake 会保留到下一次 park,不会丢失。xrtCoSleep和SleepUntil自然到期返回OK,取消返回CANCELLED。xrtCoJoin只接受同一调度器的保留句柄,支持多个等待者、deadline、取消和依赖环检测。xrtCoSchedClose停止接收新协程和新投递,并协作取消全部活跃协程;关闭前已经受理的投递仍按 FIFO 顺序排空。
投递过程运行在所属线程的普通调用栈中,不在协程内,不能调用 yield、park 或 await;它应只做创建协程、完成 Promise、更新短状态等不可阻塞操作。每次 xrtCoSchedStep 或 Poll 至多执行一个通用投递并恢复一个协程。没有活跃协程和待执行投递时返回 XWAIT_CLOSED,用户截止时间到达但仍有挂起协程时返回 XWAIT_TIMEOUT。
xrtCoSchedRun 会排空调用时已经受理的投递和由它们创建的协程。它不是永久驻留的事件循环:当活跃协程和投递同时归零时返回。销毁前必须停止其他线程访问;有尚未执行的投递时,xrtCoSchedDestroy 返回 XERR_STATE,不会静默丢弃回调或 Owned 数据。
xrtCoSchedCreate() 默认限制 1024 个尚未执行的用户投递(XRT_CO_SCHED_POST_LIMIT_DEFAULT)。xrtCoSchedCreateLimit(n) 可在创建时调整;0 使用默认值,SIZE_MAX 显式取消实际限额。队满立即返回 false / XERR_AGAIN,不接管 Owned 数据。过程从队列取出时释放名额,因此过程内部也可以继续投递。内部协程唤醒使用独立的无分配链,不受用户队列预算影响;已有批量生产者若一次提交超过 1024 项,需要显式预算或处理背压。
xrtCoWake 线程安全,但句柄销毁不是并发操作。调用方必须保证 wake 返回前目标及所属调度器仍然有效;需要跨线程管理寿命时,应由更高层 Future/Task 持有引用,而不是裸传 xcoro*。
协程事件
XRT_FEATURE_COROUTINE_EVENT 提供调度器原生的 xcoevent,用于不阻塞所属线程地等待一次跨线程通知。它依赖 coroutine_scheduler,但不依赖线程事件的内核等待对象。
xrtCoEventInit/Unit使用调用方固定存储;Create/Destroy是对应的堆对象易用层。- 自动复位事件每次
Set按 FIFO 唤醒一个等待者;没有等待者时保存一个信号。 - 手动复位事件每次
Set唤醒全部等待者并保持信号态,直到Reset。 Await、TryAwait、AwaitFor和AwaitUntil分别返回OK、TIMEOUT、CANCELLED或ERROR。- 每次 Await 使用协程栈上的等待节点,不产生堆分配;跨线程
Set通过调度器等待代际投递,不会丢失注册期间的信号。 Unit/Destroy与其他操作不能并发。只要仍有 Await 尚未返回,即使它已经获得信号,释放也会以XERR_STATE失败并保持对象有效。
通用 xrtCoWake 只能促使 Await 重新检查条件,不能伪造事件信号。终结过程中的 Await 在读取或消费事件信号前失败。
公共类型与常量
| 标识符 | 契约 |
|---|---|
xcoro | 线程归属且不透明的协程句柄。 |
xcoroproc | 协程入口过程;返回值的所有权由调用方约定。 |
xcocleanupproc | 不可挂起的清理过程。 |
xcorostate | 可恢复状态:XCORO_READY、XCORO_RUNNING、XCORO_SUSPENDED、XCORO_DONE。 |
xcoroterm | 终态原因:XCORO_TERM_NONE、XCORO_TERM_RETURNED、XCORO_TERM_CANCELLED、XCORO_TERM_ERROR。 |
xcorofinalproc | 一次性终结过程,接收终态、借用结果和借用错误快照。 |
xcoroargs | 栈大小、父取消令牌、终结过程及其数据。未指定字段保持零值。 |
xcocleanup | 调用方存储的无分配清理节点。 |
xcosched | 线程归属且不透明的调度器句柄。 |
xcoschedpostproc | 在调度器所属线程普通调用栈执行的短投递过程。 |
xcoevent | 可嵌入调用方结构的固定存储协程事件。 |
XRT_CO_CLEANUP_INIT | xcocleanup 的静态零值初始化器。 |
XRT_CORO_STACK_DEFAULT | 默认栈保留大小:64 位目标 128 KiB,32 位目标 64 KiB。 |
XRT_CORO_STACK_MIN | 最小栈保留大小 32 KiB。 |
XRT_CORO_STACK_MAX | 最大栈保留大小 64 MiB。 |
XRT_CO_EVENT_STORAGE_SIZE | 当前平台的 xcoevent 内部存储容量;不能作为跨平台 ABI 尺寸。 |
XRT_CO_SCHED_POST_LIMIT_DEFAULT | 默认外部投递队列上限:1024 项,不限制内部协程唤醒队列。 |
xcorostate类型
协程状态只描述可恢复性,退出原因由 xcoroterm 单独表达。
| 值 | 语义 |
|---|---|
XCORO_READY | 就绪 |
XCORO_RUNNING | 运行中 |
XCORO_SUSPENDED | 已挂起 |
XCORO_DONE | 已完成 |
xcoroterm类型
协程终态区分正常返回、协作取消和未处理错误。
| 值 | 语义 |
|---|---|
XCORO_TERM_NONE | 无 |
XCORO_TERM_RETURNED | RETURNED |
XCORO_TERM_CANCELLED | 已取消 |
XCORO_TERM_ERROR | 失败 |
xcoroargs类型
创建配置只保存会改变核心执行契约的选项。
| 字段 | 类型 | 语义 |
|---|---|---|
StackSize | size_t | 栈大小 |
Cancel | xcancel* | 取消令牌 |
Finalize | xcorofinalproc | Finalize |
FinalizeData | ptr | FinalizeData |
xcocleanup类型
调用方提供清理节点存储,避免每次压栈产生堆分配。
| 字段 | 类型 | 语义 |
|---|---|---|
Previous | struct xcocleanup* | Previous |
Owner | xcoro* | Owner |
Proc | xcocleanupproc | 过程指针 |
Data | ptr | 数据 |
Active | bool | Active |
Managed | bool | Managed |
xcoevent类型
协程事件允许嵌入调用方结构,不需要为对象本身分配内存。
| 字段 | 类型 | 语义 |
|---|---|---|
Alignment | uint64 | 对齐(二次幂) |
xcoro类型
协程对象对外保持不透明,并且固定归属于创建它的原生线程。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。
xcosched类型
单线程协程调度器对外保持不透明。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。
xcoroproc类型
协程过程返回的指针由调用方定义所有权。 回调类型;参数与返回语义见签名及各使用方 API 节。
xcocleanupproc类型
协程退出清理过程在所属协程的执行上下文中运行。 回调类型;参数与返回语义见签名及各使用方 API 节。
xcorofinalproc类型
终结过程接收最终终态快照,不能让出、恢复或销毁当前协程。 回调类型;参数与返回语义见签名及各使用方 API 节。
xcoschedpostproc类型
调度器投递过程运行在所属线程的普通调用栈中,适合短小的调度操作。 回调类型;参数与返回语义见签名及各使用方 API 节。
xrtCoCreate函数
创建 XCORO_READY 状态的协程对象;未恢复前不分配运行栈之外的状态。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pProc | 输入 | 非空 | 协程入口过程 |
pData | 输入 | 任意值 | 原样传给过程 |
pArgs | 输入 | 允许空 | 栈大小/父取消令牌/终结过程;空 = 全默认 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | READY 协程,归属当前线程 | — |
NULL | 参数非法、栈大小越界或分配失败 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 过程为空或pArgs字段非法XERR_RANGE— 栈大小超出 32 KiB–64 MiB 边界XERR_MEMORY— 对象或栈分配失败
范例已编译验证
concurrency/coroutine · 基础 · 创建-恢复-取结果-销毁
xcoro* pCo = xrtCoCreate(exampleCoroutine, &iValue, NULL);
if ( pCo == NULL ) {
return 1;
}
(void)xrtCoResume(pCo);
xrtCoDestroy函数
销毁未启动或已完成对象;活跃对象失败且保持有效。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 允许空 | 目标协程;只接受 READY 或 DONE 状态 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 对象已释放 | — |
false | 对象活跃或非本线程 | 对象保持有效;错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 句柄为空XERR_STATE— 栈仍活跃(拒绝跳过清理)或从其他线程销毁
范例已编译验证
concurrency/coroutine · 收尾 · 完成后销毁并 detach
(void)xrtCoDestroy(pCo); (void)xrtCoThreadDetach(); return 0;
xrtCoResume函数
在所属线程恢复协程,直到让出或完成。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空 | 目标协程;须处于 READY/SUSPENDED |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 本次恢复段已执行到让出或返回 | — |
false | 状态不可恢复或非本线程 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 句柄为空XERR_STATE—RUNNING/DONE状态或从其他线程恢复
范例已编译验证
concurrency/coroutine · 基础 · 两次恢复走完 yield 前后两段
(void)xrtCoResume(pCo);
printf("after yield: %d\n", iValue);
(void)xrtCoResume(pCo);
printf("result: %d\n", *(int*)xrtCoResult(pCo));
xrtCoYield函数
让出当前协程,并在恢复后返回取消状态。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 仅协程内可调 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 正常恢复 | — |
XWAIT_CANCELLED | 恢复时收到取消请求 | 协作取消的检查点 |
XWAIT_ERROR | 不在协程内 | XERR_STATE |
XERR_STATE— 普通调用栈(非协程)中调用
xrtCoCurrent函数
返回当前协程的借用句柄;普通调用栈返回空指针。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 无参数 |
| 返回 | 含义 |
|---|---|
| 非空 | 当前协程借用(回调期间有效) |
NULL | 普通线程调用栈(正常结果) |
- 无 — 空返回是上下文查询结果
xrtCoState函数
返回可恢复状态快照。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 允许空 | 目标协程 |
| 返回 | 含义 |
|---|---|
XCORO_READY / XCORO_RUNNING / XCORO_SUSPENDED / XCORO_DONE | 状态枚举;空句柄返回 READY(零值) |
- 无 — 快照查询
范例已编译验证
concurrency/coroutine_tour · 生命周期 · 运行中自检 + 终态核对
pJob->iRunning = xrtCoState(pSelf) == XCORO_RUNNING ? 1 : 0;
xrtCoTerm函数
仅在状态已发布为 DONE 后返回终态,否则返回 NONE。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 允许空 | 目标协程 |
| 返回 | 含义 |
|---|---|
XCORO_TERM_NONE | 尚未终结 |
XCORO_TERM_RETURNED / XCORO_TERM_CANCELLED / XCORO_TERM_ERROR | 终态原因 |
- 无 — 终态查询
范例已编译验证
concurrency/coroutine_tour · 生命周期 · 完成后核对 RETURNED
(xrtCoState(pLife) != XCORO_DONE) || (xrtCoTerm(pLife) != XCORO_TERM_RETURNED) ||
xrtCoResult函数
返回正常终态的借用结果。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 允许空 | 目标协程 |
| 返回 | 含义 |
|---|---|
| 非空 | 过程返回值(所有权由调用方约定) |
NULL | 未完成、取消终态或过程返回了空 |
- 无 — 借用查询
xrtCoError函数
返回错误终态的借用结构化错误。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 允许空 | 目标协程 |
| 返回 | 含义 |
|---|---|
| 非空 | XCORO_TERM_ERROR 终态的错误借用 |
NULL | 非错误终态或未完成 |
- 无 — 借用查询
范例已编译验证
concurrency/coroutine_tour · 生命周期 · 正常终态应为空错误
(xrtCoError(pLife) != NULL) ||
(xrtCoResult(pLife) != (ptr)1) ) {
xrtCoCancel函数
线程安全且幂等地请求协作取消,并通知可选调度器。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空 | 目标协程;可从任意线程调用 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 请求已受理(重复请求同样成功) | — |
false | 句柄为空或已终结 | 已终结不设错;空句柄设 XERR_ARGUMENT |
XERR_ARGUMENT— 句柄为空
范例已编译验证
concurrency/coroutine_lifecycle · 协作取消 · 工作协程挂起后请求取消
return xrtCoCancel(pContext->Worker) ? pContext : NULL;
xrtCoCancelToken函数
返回增加引用后的取消令牌。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空、当前协程 | 只能在协程内取自己的令牌 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 引用 +1 的令牌;调用方 xrtCancelDestroy 释放 | — |
NULL | 非协程上下文或句柄为空 | XERR_STATE / XERR_ARGUMENT |
XERR_ARGUMENT— 句柄为空XERR_STATE— 普通调用栈中调用
xrtCoStopping函数
查询当前协程是否收到取消请求。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 仅协程内有意义 |
| 返回 | 含义 |
|---|---|
true | 已收到取消请求(尚未确认) |
false | 无请求或普通线程路径(正常结果) |
- 无 — 查询语义
xrtCoConfirmCancel函数
确认用户过程返回时发布取消终态。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 仅协程内、收到请求后可调 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 终态将发布为 XCORO_TERM_CANCELLED | — |
false | 无取消请求、普通线程或清理栈中 | XERR_STATE |
XERR_STATE— 无请求或非法上下文
范例已编译验证
concurrency/coroutine_lifecycle · 协作取消 · park 被取消后确认终态
Result = xrtCoPark();
if ( Result == XWAIT_CANCELLED ) {
(void)xrtCoConfirmCancel();
}
xrtCoThreadDetach函数
释放当前外部线程的惰性协程运行时。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 外部创建的线程在最后一个协程结束后调用 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 运行时已释放 | — |
false | 仍有挂起协程 | XERR_STATE |
XERR_STATE— 仍有协程未终结
范例已编译验证
concurrency/coroutine · 收尾 · 销毁全部协程后 detach
(void)xrtCoDestroy(pCo); (void)xrtCoThreadDetach(); return 0;
xrtCoCleanupPush函数
压入零初始化、调用方存储的无分配清理节点。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCleanup | 输入/输出 | XRT_CO_CLEANUP_INIT 或全零 | 存储期须覆盖协程终态 |
pProc | 输入 | 非空 | 不可挂起的清理过程 |
pData | 输入 | 任意值 | 原样传给清理过程 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已按后进先出压栈 | — |
false | 参数非法或非协程上下文 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 指针为空XERR_STATE— 普通调用栈调用
范例已编译验证
concurrency/coroutine_lifecycle · 清理栈 · 调用方存储节点
if ( !xrtCoCleanupPush(
&pContext->ManualCleanup,
exampleCleanup,
&pContext->ManualCleaned
) ) {
xrtCoDefer函数
分配并压入由协程管理存储期的清理节点。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pProc | 输入 | 非空 | 清理过程 |
pData | 输入 | 任意值 | 原样传给清理过程 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 节点句柄,可用于提前弹出 | — |
NULL | 参数非法、非协程上下文或 OOM | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT/XERR_STATE/XERR_MEMORY
范例已编译验证
concurrency/coroutine_lifecycle · 清理栈 · 托管节点
pDeferred = xrtCoDefer(exampleCleanup, &pContext->DeferredCleaned);
if ( pDeferred == NULL ) {
return NULL;
}
xrtCoCleanupPop函数
弹出栈顶节点,并可立即执行清理过程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCleanup | 输入 | 非空、栈顶节点 | Defer 句柄或 CleanupPush 节点 |
bRun | 输入 | — | 为真时立即执行清理过程 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已弹出(并按需执行) | — |
false | 节点不在栈顶或非协程上下文 | XERR_STATE |
XERR_ARGUMENT— 指针为空XERR_STATE— 节点非栈顶
范例已编译验证
concurrency/coroutine_lifecycle · 清理栈 · 失败路径弹出托管节点
(void)xrtCoCleanupPop(pDeferred, true); return NULL;
xrtCoBackend函数
返回当前目标的静态后端名称。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 无参数 |
| 返回 | 含义 |
|---|---|
cstr | 静态字符串(如 "fiber"、"asm"),进程存活期有效 |
- 无 — 静态查询
xrtCoSchedCreate函数
在当前线程创建调度器;默认投递上限 1024。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 无参数 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 归属当前线程的调度器 | — |
NULL | 分配失败 | XERR_MEMORY |
XERR_MEMORY— 调度器结构分配失败
范例已编译验证
concurrency/coroutine_event · 事件 · 创建后 spawn 消费者
pSched = xrtCoSchedCreate();
if ( pSched == NULL ) {
(void)xrtCoEventUnit(&tEvent);
return 1;
}
xrtCoSchedCreateLimit函数
创建时指定用户投递上限;0 使用默认 1024。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iPostLimit | 输入 | — | 尚未执行的用户投递上限;0 = 默认,SIZE_MAX = 不限 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 调度器 | — |
NULL | 分配失败 | XERR_MEMORY |
XERR_MEMORY— 分配失败
xrtCoSchedDestroy函数
销毁空闲调度器及其保留的完成句柄。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 允许空 | 须在所属线程且无未执行投递 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 调度器与保留句柄已释放 | — |
false | 仍有未执行投递或活跃协程句柄 | 不静默丢弃;错误经 xrtGetError() 报告 |
XERR_STATE— 有未执行投递/保留句柄未销毁,或非所属线程
xrtCoSchedCurrent函数
返回当前协程所属的借用调度器。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 无参数 |
| 返回 | 含义 |
|---|---|
| 非空 | 当前协程的调度器借用 |
NULL | 普通调用栈(正常结果) |
- 无 — 上下文查询
xrtCoSchedPost函数
从任意线程 FIFO 投递借用数据过程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空 | 目标调度器 |
pProc | 输入 | 非空 | 所属线程普通栈执行的短过程 |
pData | 输入 | 借用 | 原样传给过程 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已入队 | — |
false | 队满、已关闭或参数非法 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 指针为空XERR_AGAIN— 投递队列达到上限(背压)XERR_STATE— 调度器已 Close
范例已编译验证
concurrency/coroutine_tour · 单步模式 · 投递后单步执行
!xrtCoSchedPost(pStep, examplePostProc, NULL) || (xrtCoSchedAlive(pStep) != 0u) || (xrtCoSchedStep(pStep) != XWAIT_OK) ||
xrtCoSchedPostOwned函数
从任意线程投递过程并接管数据;失败不接管,受理后在过程返回后恰好析构一次。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空 | 目标调度器 |
pProc | 输入 | 非空 | 短过程 |
pData | 输入 | 成功受理后移交 | 数据所有权 |
pDestroy | 输入 | 非空 | 析构过程,恰好执行一次 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已受理;析构由调度器保证 | — |
false | 队满、已关闭或参数非法 | 数据仍归调用方 |
XERR_ARGUMENT/XERR_AGAIN/XERR_STATE— 同xrtCoSchedPost
范例已编译验证
concurrency/coroutine_tour · PostOwned · 析构恰好一次核对
if ( !xrtCoSchedPostOwned(pSched, examplePostProc, (ptr)7,
examplePostDestroy) ||
!xrtCoSchedRun(pSched) ||
(g_Destroyed != 1) ) {
xrtCoSpawn函数
创建由调度器管理且在完成后保留句柄的协程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空、未关闭 | 所属调度器 |
pProc | 输入 | 非空 | 协程过程 |
pData | 输入 | 任意值 | 过程数据 |
pArgs | 输入 | 允许空 | 栈/令牌/终结配置 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 保留句柄;完成后可读终态,最后 Destroy | — |
NULL | 调度器关闭、参数非法或 OOM | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT/XERR_STATE(已关闭)/XERR_MEMORY
范例已编译验证
concurrency/coroutine_tour · 生命周期 · spawn 后 Run 到完成
pLife = xrtCoSpawn(pSched, exampleCoLife, &Life, NULL);
if ( (pLife == NULL) || !xrtCoSchedRun(pSched) ) {
goto Cleanup;
}
xrtCoGo函数
创建完成后由调度器自动回收的分离协程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空、未关闭 | 所属调度器 |
pProc | 输入 | 非空 | 协程过程 |
pData | 输入 | 任意值 | 过程数据 |
pArgs | 输入 | 允许空 | 配置 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已受理;完成后自动回收,无句柄 | — |
false | 同 xrtCoSpawn 失败条件 | 错误经 xrtGetError() 报告 |
- 同
xrtCoSpawn
范例已编译验证
concurrency/coroutine_lifecycle · 三协程同场 · 工作协程 + 两个 Go 辅助
xrtCoGo(pSched, exampleCancel, &Context, NULL) &&
xrtCoGo(pSched, exampleJoin, &Context, NULL) ) {
xrtCoSchedClose函数
请求取消全部活跃协程并停止接收新协程和新投递。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空 | 目标调度器;幂等 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已停止受理;已受理投递仍按 FIFO 排空 | — |
false | 指针非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空
范例已编译验证
concurrency/coroutine_lifecycle · 失败路径 · spawn 失败时关闭排空
(void)xrtCoSchedClose(pSched); (void)xrtCoSchedRun(pSched);
xrtCoSchedStep函数
非阻塞地执行至多一个投递和一个就绪协程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空、所属线程 | 目标调度器 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 执行了工作 | — |
XWAIT_CLOSED | 无活跃协程与待执行投递 | 正常排空结果 |
XWAIT_ERROR | 参数或状态错误 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 指针为空XERR_STATE— 非所属线程
xrtCoSchedPollFor函数
在相对毫秒期限内等待,并执行至多一个调度步。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空、所属线程 | 目标调度器 |
iTimeout | 输入 | 毫秒 | 等待期限 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 执行了工作 | — |
XWAIT_TIMEOUT | 到期但仍有挂起协程 | 正常结果 |
XWAIT_CLOSED | 全部排空 | 正常结果 |
XWAIT_ERROR | 参数/状态错误 | 错误经 xrtGetError() 报告 |
- 同
xrtCoSchedStep
范例已编译验证
concurrency/coroutine_tour · 单步模式 · 期限轮询
(xrtCoSchedPollFor(pStep, EXAMPLE_LONG_MS) != XWAIT_OK) ||
xrtCoSchedRun函数
运行到活跃协程和已受理投递全部排空。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 非空、所属线程 | 目标调度器 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已排空(不驻留的事件循环) | — |
false | 参数/状态错误 | 错误经 xrtGetError() 报告 |
XERR_ARGUMENT— 指针为空XERR_STATE— 非所属线程
范例已编译验证
concurrency/coroutine_event · 事件 · 消费者 + 生产者一次排空
bOkay = (pConsumer != NULL) && xrtCoGo(pSched, producer, &tEvent, NULL) && xrtCoSchedRun(pSched) && (xrtCoResult(pConsumer) == &tEvent) &&
xrtCoSchedAlive函数
在所属线程返回尚未完成的协程数量。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pSched | 输入 | 允许空 | 目标调度器 |
| 返回 | 含义 |
|---|---|
>= 0 | 活跃协程计数(含分离协程) |
0 | 无活跃协程或句柄为空 |
- 无 — 计数查询
xrtCoWake函数
线程安全且幂等地唤醒仍然有效的调度协程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空 | 目标协程;句柄销毁不是并发操作 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 唤醒已投递(提前 wake 保留到下一次 park) | — |
false | 句柄为空或非调度协程 | XERR_ARGUMENT / XERR_STATE |
XERR_ARGUMENT— 句柄为空XERR_STATE— 目标不由调度器管理
xrtCoPark函数
挂起当前协程直到 wake 或取消。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
| 无 | — | — | 仅调度协程内可调 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 被 wake 唤醒 | — |
XWAIT_CANCELLED | 收到取消请求 | 协作检查点 |
XWAIT_ERROR | 非调度协程上下文 | XERR_STATE |
XERR_STATE— 普通协程或普通调用栈
范例已编译验证
concurrency/coroutine_lifecycle · 协作取消 · park 被取消打断
Result = xrtCoPark();
if ( Result == XWAIT_CANCELLED ) {
(void)xrtCoConfirmCancel();
}
xrtCoParkFor函数
挂起到相对毫秒期限、wake 或取消。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iTimeout | 输入 | 毫秒 | 相对期限 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK / XWAIT_TIMEOUT / XWAIT_CANCELLED | wake/到期/取消 | — |
XWAIT_ERROR | 非调度协程 | XERR_STATE |
XERR_STATE— 非调度协程上下文
范例已编译验证
concurrency/coroutine_tour · Join/Park · 被唤醒返回 OK
pJob->iForResult = (int)xrtCoParkFor(EXAMPLE_LONG_MS);
xrtCoSleep函数
睡眠相对毫秒数;自然到期或提前 wake 返回 OK。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iTimeout | 输入 | 毫秒 | 睡眠时长 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 到期或被 wake 提前结束 | — |
XWAIT_CANCELLED | 取消请求打断 | — |
XWAIT_ERROR | 非调度协程 | XERR_STATE |
XERR_STATE— 非调度协程上下文
xrtCoSleepFor函数
睡眠到绝对截止时间。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iTimeout | 输入 | 单调时钟 | 绝对截止时间 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK / XWAIT_CANCELLED | 到期/取消 | — |
XWAIT_ERROR | 非调度协程 | XERR_STATE |
XERR_STATE— 非调度协程上下文
xrtCoJoin函数
等待同一调度器的保留句柄完成。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空 | 保留句柄;须与等待者同调度器 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 目标已完成 | — |
XWAIT_CANCELLED | 等待者自身被取消 | — |
XWAIT_ERROR | 参数非法或跨调度器 | XERR_ARGUMENT / XERR_STATE |
XERR_ARGUMENT— 句柄为空或分离协程XERR_STATE— 跨调度器 join 或检测到依赖环
范例已编译验证
concurrency/coroutine_lifecycle · Join · 同调度器等待工作协程
pContext->JoinResult = xrtCoJoin(pContext->Worker);
xrtCoJoinFor函数
在相对毫秒期限内等待目标完成。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pCo | 输入 | 非空 | 保留句柄 |
iTimeout | 输入 | 毫秒 | 相对期限 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK / XWAIT_TIMEOUT / XWAIT_CANCELLED | 完成/到期/取消 | — |
XWAIT_ERROR | 同 xrtCoJoin 错误条件 | 错误经 xrtGetError() 报告 |
- 同
xrtCoJoin
范例已编译验证
concurrency/coroutine_tour · Join/Park · 短窗超时
pJob->iForResult = (int)xrtCoJoinFor(pJob->pTarget,
xrtCoEventInit函数
初始化调用方存储的自动或手动复位事件。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输出 | 非空 | 固定存储(可嵌入调用方结构) |
bManualReset | 输入 | — | 手动复位唤醒全部;自动复位按 FIFO 唤醒一个 |
bSignaled | 输入 | — | 初始信号态 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 事件已就绪 | — |
false | 指针非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空
范例已编译验证
concurrency/coroutine_event · 事件 · 自动复位、无初始信号
if ( !xrtCoEventInit(&tEvent, false, false) ) {
return 1;
}
xrtCoEventUnit函数
释放协程事件;仍有尚未返回的等待者时失败并保持对象有效。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | Init 产物;与其他操作不能并发 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 固定存储已释放 | — |
false | 仍有 Await 未返回 | 对象保持有效;XERR_STATE |
XERR_ARGUMENT— 指针为空XERR_STATE— 仍有等待者(即使已获信号)
范例已编译验证
concurrency/coroutine_event · 收尾 · 排空后释放
(void)xrtCoSchedDestroy(pSched); (void)xrtCoEventUnit(&tEvent); (void)xrtCoThreadDetach();
xrtCoEventCreate函数
创建自动或手动复位协程事件(堆存储易用层)。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
bManualReset | 输入 | — | 复位模式 |
bSignaled | 输入 | — | 初始信号态 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 堆事件;EventDestroy 释放 | — |
NULL | 分配失败 | XERR_MEMORY |
XERR_MEMORY— 分配失败
范例已编译验证
concurrency/coroutine_tour · 事件族 · 自动复位事件
pAuto = xrtCoEventCreate(false, false);
if ( (pAuto == NULL) || !xrtCoEventSet(pAuto) ) {
goto Cleanup; /* 预置位供 TryAwait 立即消费 */
}
xrtCoEventDestroy函数
释放 Create 返回的协程事件;仍有等待者时失败且不释放对象。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 允许空 | Create 产物 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已释放 | — |
false | 仍有等待者 | 对象不释放;XERR_STATE |
XERR_STATE— 仍有 Await 未返回
范例已编译验证
concurrency/coroutine_tour · 事件族 · 全部唤醒核对后销毁
if ( (pWaiter == NULL) || (pEvtDriver == NULL) ||
!xrtCoSchedRun(pSched) ||
(Evt.iWoken != 3) ||
!xrtCoEventDestroy(pAuto) ) {
xrtCoEventSet函数
置位事件;手动复位唤醒全部等待者,自动复位按 FIFO 唤醒一个。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | 目标事件;线程安全 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已置位并投递唤醒 | — |
false | 指针非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空
xrtCoEventReset函数
清除事件的信号态;已经获得信号的等待者不受影响。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | 目标事件 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 后续等待不再看到信号 | — |
false | 指针非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空
范例已编译验证
concurrency/coroutine_tour · 事件族 · 双 Set 后清信号覆盖
(void)xrtCoEventReset(pJob->pAuto); /* 清信号(覆盖点) */
xrtCoEventAwait函数
挂起当前调度协程,直到事件置位或协程取消。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | 目标事件 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 取得信号(自动复位信号被消费) | — |
XWAIT_CANCELLED | 协程被取消 | — |
XWAIT_ERROR | 非调度协程或终结过程内 | XERR_STATE |
XERR_ARGUMENT— 指针为空XERR_STATE— 非调度协程,或终结过程中调用
xrtCoEventTryAwait函数
非阻塞地检查并消费自动复位事件。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | 目标事件 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK | 有信号并已消费(自动复位) | — |
XWAIT_TIMEOUT | 无信号(正常结果) | 不设错 |
XWAIT_CANCELLED | 已取消 | — |
XWAIT_ERROR | 参数/状态错误 | 错误经 xrtGetError() 报告 |
- 同
xrtCoEventAwait
范例已编译验证
concurrency/coroutine_tour · 事件族 · 预置位立即消费
if ( xrtCoEventTryAwait(pJob->pAuto) == XWAIT_OK ) {
xrtCoEventAwaitFor函数
在相对毫秒数内等待事件置位。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pEvent | 输入 | 非空 | 目标事件 |
iTimeout | 输入 | 毫秒 | 相对期限 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWAIT_OK / XWAIT_TIMEOUT / XWAIT_CANCELLED | 信号/到期/取消 | — |
XWAIT_ERROR | 参数/状态错误 | 错误经 xrtGetError() 报告 |
- 同
xrtCoEventAwait
范例已编译验证
concurrency/coroutine_tour · 事件族 · 期限等待由 Set 唤醒
if ( xrtCoEventAwaitFor(pJob->pAuto, EXAMPLE_LONG_MS) ==
常量索引常量
以下常量在本页所属头文件中定义,语义见公共头注释。
| 常量 | 说明 |
|---|---|
| XCORO_DONE | 见头文件注释 |
| XCORO_READY | 见头文件注释 |
| XCORO_RUNNING | 见头文件注释 |
| XCORO_SUSPENDED | 见头文件注释 |
| XCORO_TERM_CANCELLED | 见头文件注释 |
| XCORO_TERM_ERROR | 见头文件注释 |
| XCORO_TERM_NONE | 见头文件注释 |
| XCORO_TERM_RETURNED | 见头文件注释 |
| XRT_CORO_STACK_DEFAULT | 见头文件注释 |
| XRT_CORO_STACK_MAX | 见头文件注释 |
| XRT_CORO_STACK_MIN | 见头文件注释 |
| XRT_CO_CLEANUP_INIT | 见头文件注释 |
| XRT_CO_EVENT_STORAGE_SIZE | 见头文件注释 |
| XRT_CO_SCHED_POST_LIMIT_DEFAULT | 见头文件注释 |