执行契约

  • 协程固定归属于创建它的原生线程,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/ARM64FiberCreateFiberEx 保留上限、按需提交
POSIX x86-64原生汇编mmap 惰性页面和保护页
POSIX ARM64AAPCS64 原生汇编mmap 惰性页面和保护页
POSIX RISC-V 64LP64 原生汇编,按浮点 ABI 保存mmap 惰性页面和保护页
POSIX LoongArch64LP64 原生汇编,按浮点 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_INITxcocleanup 的静态零值初始化器。
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已完成
typedef enum xcorostate { XCORO_READY = 0, XCORO_RUNNING = 1, XCORO_SUSPENDED = 2, XCORO_DONE = 3 } xcorostate;

xcoroterm类型

协程终态区分正常返回、协作取消和未处理错误。

值语义
XCORO_TERM_NONE无
XCORO_TERM_RETURNEDRETURNED
XCORO_TERM_CANCELLED已取消
XCORO_TERM_ERROR失败
typedef enum xcoroterm { XCORO_TERM_NONE = 0, XCORO_TERM_RETURNED = 1, XCORO_TERM_CANCELLED = 2, XCORO_TERM_ERROR = 3 } xcoroterm;

xcoroargs类型

创建配置只保存会改变核心执行契约的选项。

字段类型语义
StackSizesize_t栈大小
Cancelxcancel*取消令牌
FinalizexcorofinalprocFinalize
FinalizeDataptrFinalizeData
typedef struct xcoroargs { size_t StackSize; xcancel* Cancel; xcorofinalproc Finalize; ptr FinalizeData; } xcoroargs;

xcocleanup类型

调用方提供清理节点存储,避免每次压栈产生堆分配。

字段类型语义
Previousstruct xcocleanup*Previous
Ownerxcoro*Owner
Procxcocleanupproc过程指针
Dataptr数据
ActiveboolActive
ManagedboolManaged
typedef struct xcocleanup { struct xcocleanup* Previous; xcoro* Owner; xcocleanupproc Proc; ptr Data; bool Active; bool Managed; } xcocleanup;

xcoevent类型

协程事件允许嵌入调用方结构,不需要为对象本身分配内存。

字段类型语义
Alignmentuint64对齐(二次幂)
typedef union xcoevent { uint64 Alignment; uint8 Storage[XRT_CO_EVENT_STORAGE_SIZE]; } xcoevent;

xcoro类型

协程对象对外保持不透明,并且固定归属于创建它的原生线程。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。

typedef struct xcoro xcoro;

xcosched类型

单线程协程调度器对外保持不透明。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。

typedef struct xcosched xcosched;

xcoroproc类型

协程过程返回的指针由调用方定义所有权。 回调类型;参数与返回语义见签名及各使用方 API 节。

typedef ptr(*xcoroproc)(ptr pData)

xcocleanupproc类型

协程退出清理过程在所属协程的执行上下文中运行。 回调类型;参数与返回语义见签名及各使用方 API 节。

typedef void(*xcocleanupproc)(ptr pData)

xcorofinalproc类型

终结过程接收最终终态快照,不能让出、恢复或销毁当前协程。 回调类型;参数与返回语义见签名及各使用方 API 节。

typedef void(*xcorofinalproc)( xcoroterm Term, ptr pResult, const xerror* pError, ptr pData)

xcoschedpostproc类型

调度器投递过程运行在所属线程的普通调用栈中,适合短小的调度操作。 回调类型;参数与返回语义见签名及各使用方 API 节。

typedef void(*xcoschedpostproc)(xcosched* pSched, ptr pData)
协程核心

xrtCoCreate函数

创建 XCORO_READY 状态的协程对象;未恢复前不分配运行栈之外的状态。

xcoro* xrtCoCreate(xcoroproc pProc, ptr pData, const xcoroargs* pArgs)

参数

参数方向约束说明
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函数

销毁未启动或已完成对象;活跃对象失败且保持有效。

bool xrtCoDestroy(xcoro* pCo)

参数

参数方向约束说明
pCo输入允许空目标协程;只接受 READY 或 DONE 状态
返回值
返回含义失败时状态
true对象已释放—
false对象活跃或非本线程对象保持有效;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 句柄为空
  • XERR_STATE — 栈仍活跃(拒绝跳过清理)或从其他线程销毁

范例已编译验证

concurrency/coroutine · 收尾 · 完成后销毁并 detach

(void)xrtCoDestroy(pCo);
(void)xrtCoThreadDetach();
return 0;

xrtCoResume函数

在所属线程恢复协程,直到让出或完成。

bool xrtCoResume(xcoro* pCo)

参数

参数方向约束说明
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函数

让出当前协程,并在恢复后返回取消状态。

xwaitresult xrtCoYield()

参数

参数方向约束说明
无——仅协程内可调
返回值
返回含义失败时状态
XWAIT_OK正常恢复—
XWAIT_CANCELLED恢复时收到取消请求协作取消的检查点
XWAIT_ERROR不在协程内XERR_STATE
错误
  • XERR_STATE — 普通调用栈(非协程)中调用

范例已编译验证

concurrency/coroutine · 基础 · yield 即取消检查点

if ( xrtCoYield() != XWAIT_OK ) {
	return NULL;
}

xrtCoCurrent函数

返回当前协程的借用句柄;普通调用栈返回空指针。

xcoro* xrtCoCurrent()

参数

参数方向约束说明
无——无参数
返回值
返回含义
非空当前协程借用(回调期间有效)
NULL普通线程调用栈(正常结果)
错误
  • 无 — 空返回是上下文查询结果

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 协程内自省起点

xcoro* pSelf = xrtCoCurrent();

xrtCoState函数

返回可恢复状态快照。

xcorostate xrtCoState(const xcoro* pCo)

参数

参数方向约束说明
pCo输入允许空目标协程
返回值
返回含义
XCORO_READY / XCORO_RUNNING / XCORO_SUSPENDED / XCORO_DONE状态枚举;空句柄返回 READY(零值)
错误
  • 无 — 快照查询

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 运行中自检 + 终态核对

pJob->iRunning = xrtCoState(pSelf) == XCORO_RUNNING ? 1 : 0;

xrtCoTerm函数

仅在状态已发布为 DONE 后返回终态,否则返回 NONE。

xcoroterm xrtCoTerm(const xcoro* pCo)

参数

参数方向约束说明
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函数

返回正常终态的借用结果。

ptr xrtCoResult(const xcoro* pCo)

参数

参数方向约束说明
pCo输入允许空目标协程
返回值
返回含义
非空过程返回值(所有权由调用方约定)
NULL未完成、取消终态或过程返回了空
错误
  • 无 — 借用查询

范例已编译验证

concurrency/coroutine · 取结果 · 完成后读取返回值

printf("result: %d\n", *(int*)xrtCoResult(pCo));

xrtCoError函数

返回错误终态的借用结构化错误。

const xerror* xrtCoError(const xcoro* pCo)

参数

参数方向约束说明
pCo输入允许空目标协程
返回值
返回含义
非空XCORO_TERM_ERROR 终态的错误借用
NULL非错误终态或未完成
错误
  • 无 — 借用查询

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 正常终态应为空错误

(xrtCoError(pLife) != NULL) ||
(xrtCoResult(pLife) != (ptr)1) ) {

xrtCoCancel函数

线程安全且幂等地请求协作取消,并通知可选调度器。

bool xrtCoCancel(xcoro* pCo)

参数

参数方向约束说明
pCo输入非空目标协程;可从任意线程调用
返回值
返回含义失败时状态
true请求已受理(重复请求同样成功)—
false句柄为空或已终结已终结不设错;空句柄设 XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 句柄为空

范例已编译验证

concurrency/coroutine_lifecycle · 协作取消 · 工作协程挂起后请求取消

return xrtCoCancel(pContext->Worker) ? pContext : NULL;

xrtCoCancelToken函数

返回增加引用后的取消令牌。

xcancel* xrtCoCancelToken(const xcoro* pCo)

参数

参数方向约束说明
pCo输入非空、当前协程只能在协程内取自己的令牌
返回值
返回含义失败时状态
非空引用 +1 的令牌;调用方 xrtCancelDestroy 释放—
NULL非协程上下文或句柄为空XERR_STATE / XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 句柄为空
  • XERR_STATE — 普通调用栈中调用

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 协程内取令牌传给可中断等待

pJob->pToken = xrtCoCancelToken(pSelf);

xrtCoStopping函数

查询当前协程是否收到取消请求。

bool xrtCoStopping()

参数

参数方向约束说明
无——仅协程内有意义
返回值
返回含义
true已收到取消请求(尚未确认)
false无请求或普通线程路径(正常结果)
错误
  • 无 — 查询语义

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 自省字段之一

pJob->iStopping = xrtCoStopping() ? 1 : 0;

xrtCoConfirmCancel函数

确认用户过程返回时发布取消终态。

bool xrtCoConfirmCancel()

参数

参数方向约束说明
无——仅协程内、收到请求后可调
返回值
返回含义失败时状态
true终态将发布为 XCORO_TERM_CANCELLED—
false无取消请求、普通线程或清理栈中XERR_STATE
错误
  • XERR_STATE — 无请求或非法上下文

范例已编译验证

concurrency/coroutine_lifecycle · 协作取消 · park 被取消后确认终态

Result = xrtCoPark();
if ( Result == XWAIT_CANCELLED ) {
	(void)xrtCoConfirmCancel();
}

xrtCoThreadDetach函数

释放当前外部线程的惰性协程运行时。

bool xrtCoThreadDetach()

参数

参数方向约束说明
无——外部创建的线程在最后一个协程结束后调用
返回值
返回含义失败时状态
true运行时已释放—
false仍有挂起协程XERR_STATE
错误
  • XERR_STATE — 仍有协程未终结

范例已编译验证

concurrency/coroutine · 收尾 · 销毁全部协程后 detach

(void)xrtCoDestroy(pCo);
(void)xrtCoThreadDetach();
return 0;

xrtCoCleanupPush函数

压入零初始化、调用方存储的无分配清理节点。

bool xrtCoCleanupPush(xcocleanup* pCleanup, xcocleanupproc pProc, ptr pData)

参数

参数方向约束说明
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函数

分配并压入由协程管理存储期的清理节点。

xcocleanup* xrtCoDefer(xcocleanupproc pProc, ptr pData)

参数

参数方向约束说明
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函数

弹出栈顶节点,并可立即执行清理过程。

bool xrtCoCleanupPop(xcocleanup* pCleanup, bool bRun)

参数

参数方向约束说明
pCleanup输入非空、栈顶节点Defer 句柄或 CleanupPush 节点
bRun输入—为真时立即执行清理过程
返回值
返回含义失败时状态
true已弹出(并按需执行)—
false节点不在栈顶或非协程上下文XERR_STATE
错误
  • XERR_ARGUMENT — 指针为空
  • XERR_STATE — 节点非栈顶

范例已编译验证

concurrency/coroutine_lifecycle · 清理栈 · 失败路径弹出托管节点

(void)xrtCoCleanupPop(pDeferred, true);
return NULL;

xrtCoBackend函数

返回当前目标的静态后端名称。

cstr xrtCoBackend()

参数

参数方向约束说明
无——无参数
返回值
返回含义
cstr静态字符串(如 "fiber"、"asm"),进程存活期有效
错误
  • 无 — 静态查询

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 自省字段之一

pJob->sBackend = xrtCoBackend();
调度器

xrtCoSchedCreate函数

在当前线程创建调度器;默认投递上限 1024。

xcosched* xrtCoSchedCreate()

参数

参数方向约束说明
无——无参数
返回值
返回含义失败时状态
非空归属当前线程的调度器—
NULL分配失败XERR_MEMORY
错误
  • XERR_MEMORY — 调度器结构分配失败

范例已编译验证

concurrency/coroutine_event · 事件 · 创建后 spawn 消费者

pSched = xrtCoSchedCreate();
if ( pSched == NULL ) {
	(void)xrtCoEventUnit(&tEvent);
	return 1;
}

xrtCoSchedCreateLimit函数

创建时指定用户投递上限;0 使用默认 1024。

xcosched* xrtCoSchedCreateLimit(size_t iPostLimit)

参数

参数方向约束说明
iPostLimit输入—尚未执行的用户投递上限;0 = 默认,SIZE_MAX = 不限
返回值
返回含义失败时状态
非空调度器—
NULL分配失败XERR_MEMORY
错误
  • XERR_MEMORY — 分配失败

范例已编译验证

concurrency/coroutine_tour · 单步模式 · 显式 16 项上限

pStep = xrtCoSchedCreateLimit(16u);

xrtCoSchedDestroy函数

销毁空闲调度器及其保留的完成句柄。

bool xrtCoSchedDestroy(xcosched* pSched)

参数

参数方向约束说明
pSched输入允许空须在所属线程且无未执行投递
返回值
返回含义失败时状态
true调度器与保留句柄已释放—
false仍有未执行投递或活跃协程句柄不静默丢弃;错误经 xrtGetError() 报告
错误
  • XERR_STATE — 有未执行投递/保留句柄未销毁,或非所属线程

范例已编译验证

concurrency/coroutine_tour · 单步模式 · 排空后销毁

!xrtCoSchedDestroy(pStep) ) {
	goto Cleanup;
}

xrtCoSchedCurrent函数

返回当前协程所属的借用调度器。

xcosched* xrtCoSchedCurrent()

参数

参数方向约束说明
无——无参数
返回值
返回含义
非空当前协程的调度器借用
NULL普通调用栈(正常结果)
错误
  • 无 — 上下文查询

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 协程内反查调度器

pJob->pSched = xrtCoSchedCurrent();

xrtCoSchedPost函数

从任意线程 FIFO 投递借用数据过程。

bool xrtCoSchedPost(xcosched* pSched, xcoschedpostproc pProc, ptr pData)

参数

参数方向约束说明
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函数

从任意线程投递过程并接管数据;失败不接管,受理后在过程返回后恰好析构一次。

bool xrtCoSchedPostOwned(xcosched* pSched, xcoschedpostproc pProc, ptr pData, xcocleanupproc pDestroy)

参数

参数方向约束说明
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函数

创建由调度器管理且在完成后保留句柄的协程。

xcoro* xrtCoSpawn(xcosched* pSched, xcoroproc pProc, ptr pData, const xcoroargs* pArgs)

参数

参数方向约束说明
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函数

创建完成后由调度器自动回收的分离协程。

bool xrtCoGo(xcosched* pSched, xcoroproc pProc, ptr pData, const xcoroargs* pArgs)

参数

参数方向约束说明
pSched输入非空、未关闭所属调度器
pProc输入非空协程过程
pData输入任意值过程数据
pArgs输入允许空配置
返回值
返回含义失败时状态
true已受理;完成后自动回收,无句柄—
false同 xrtCoSpawn 失败条件错误经 xrtGetError() 报告
错误
  • 同 xrtCoSpawn

范例已编译验证

concurrency/coroutine_lifecycle · 三协程同场 · 工作协程 + 两个 Go 辅助

xrtCoGo(pSched, exampleCancel, &Context, NULL) &&
xrtCoGo(pSched, exampleJoin, &Context, NULL) ) {

xrtCoSchedClose函数

请求取消全部活跃协程并停止接收新协程和新投递。

bool xrtCoSchedClose(xcosched* pSched)

参数

参数方向约束说明
pSched输入非空目标调度器;幂等
返回值
返回含义失败时状态
true已停止受理;已受理投递仍按 FIFO 排空—
false指针非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空

范例已编译验证

concurrency/coroutine_lifecycle · 失败路径 · spawn 失败时关闭排空

(void)xrtCoSchedClose(pSched);
(void)xrtCoSchedRun(pSched);

xrtCoSchedStep函数

非阻塞地执行至多一个投递和一个就绪协程。

xwaitresult xrtCoSchedStep(xcosched* pSched)

参数

参数方向约束说明
pSched输入非空、所属线程目标调度器
返回值
返回含义失败时状态
XWAIT_OK执行了工作—
XWAIT_CLOSED无活跃协程与待执行投递正常排空结果
XWAIT_ERROR参数或状态错误错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空
  • XERR_STATE — 非所属线程

范例已编译验证

concurrency/coroutine_tour · 单步模式 · 投递后单步执行

(xrtCoSchedStep(pStep) != XWAIT_OK) ||

xrtCoSchedPollFor函数

在相对毫秒期限内等待,并执行至多一个调度步。

xwaitresult xrtCoSchedPollFor(xcosched* pSched, int64 iTimeout)

参数

参数方向约束说明
pSched输入非空、所属线程目标调度器
iTimeout输入毫秒等待期限
返回值
返回含义失败时状态
XWAIT_OK执行了工作—
XWAIT_TIMEOUT到期但仍有挂起协程正常结果
XWAIT_CLOSED全部排空正常结果
XWAIT_ERROR参数/状态错误错误经 xrtGetError() 报告
错误
  • 同 xrtCoSchedStep

范例已编译验证

concurrency/coroutine_tour · 单步模式 · 期限轮询

(xrtCoSchedPollFor(pStep, EXAMPLE_LONG_MS) !=
	XWAIT_OK) ||

xrtCoSchedRun函数

运行到活跃协程和已受理投递全部排空。

bool xrtCoSchedRun(xcosched* pSched)

参数

参数方向约束说明
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函数

在所属线程返回尚未完成的协程数量。

size_t xrtCoSchedAlive(const xcosched* pSched)

参数

参数方向约束说明
pSched输入允许空目标调度器
返回值
返回含义
>= 0活跃协程计数(含分离协程)
0无活跃协程或句柄为空
错误
  • 无 — 计数查询

范例已编译验证

concurrency/coroutine_tour · 单步模式 · 空转核对为零

(xrtCoSchedAlive(pStep) != 0u) ||

xrtCoWake函数

线程安全且幂等地唤醒仍然有效的调度协程。

bool xrtCoWake(xcoro* pCo)

参数

参数方向约束说明
pCo输入非空目标协程;句柄销毁不是并发操作
返回值
返回含义失败时状态
true唤醒已投递(提前 wake 保留到下一次 park)—
false句柄为空或非调度协程XERR_ARGUMENT / XERR_STATE
错误
  • XERR_ARGUMENT — 句柄为空
  • XERR_STATE — 目标不由调度器管理

范例已编译验证

concurrency/coroutine_tour · Join/Park · 唤醒挂起的 parker

(void)xrtCoWake(pParker);

xrtCoPark函数

挂起当前协程直到 wake 或取消。

xwaitresult xrtCoPark()

参数

参数方向约束说明
无——仅调度协程内可调
返回值
返回含义失败时状态
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 或取消。

xwaitresult xrtCoParkFor(int64 iTimeout)

参数

参数方向约束说明
iTimeout输入毫秒相对期限
返回值
返回含义失败时状态
XWAIT_OK / XWAIT_TIMEOUT / XWAIT_CANCELLEDwake/到期/取消—
XWAIT_ERROR非调度协程XERR_STATE
错误
  • XERR_STATE — 非调度协程上下文

范例已编译验证

concurrency/coroutine_tour · Join/Park · 被唤醒返回 OK

pJob->iForResult = (int)xrtCoParkFor(EXAMPLE_LONG_MS);

xrtCoSleep函数

睡眠相对毫秒数;自然到期或提前 wake 返回 OK。

xwaitresult xrtCoSleep(int64 iTimeout)

参数

参数方向约束说明
iTimeout输入毫秒睡眠时长
返回值
返回含义失败时状态
XWAIT_OK到期或被 wake 提前结束—
XWAIT_CANCELLED取消请求打断—
XWAIT_ERROR非调度协程XERR_STATE
错误
  • XERR_STATE — 非调度协程上下文

范例已编译验证

concurrency/coroutine_event · 生产者 · 短睡后置位事件

if ( xrtCoSleep(1000) != XWAIT_OK ) {

xrtCoSleepFor函数

睡眠到绝对截止时间。

xwaitresult xrtCoSleepFor(int64 iTimeout)

参数

参数方向约束说明
iTimeout输入单调时钟绝对截止时间
返回值
返回含义失败时状态
XWAIT_OK / XWAIT_CANCELLED到期/取消—
XWAIT_ERROR非调度协程XERR_STATE
错误
  • XERR_STATE — 非调度协程上下文

范例已编译验证

concurrency/coroutine_tour · 生命周期 · 协程内短睡

(void)xrtCoSleepFor(EXAMPLE_SHORT_MS);

xrtCoJoin函数

等待同一调度器的保留句柄完成。

xwaitresult xrtCoJoin(xcoro* pCo)

参数

参数方向约束说明
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函数

在相对毫秒期限内等待目标完成。

xwaitresult xrtCoJoinFor(xcoro* pCo, int64 iTimeout)

参数

参数方向约束说明
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函数

初始化调用方存储的自动或手动复位事件。

bool xrtCoEventInit(xcoevent* pEvent, bool bManualReset, bool bSignaled)

参数

参数方向约束说明
pEvent输出非空固定存储(可嵌入调用方结构)
bManualReset输入—手动复位唤醒全部;自动复位按 FIFO 唤醒一个
bSignaled输入—初始信号态
返回值
返回含义失败时状态
true事件已就绪—
false指针非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空

范例已编译验证

concurrency/coroutine_event · 事件 · 自动复位、无初始信号

if ( !xrtCoEventInit(&tEvent, false, false) ) {
	return 1;
}

xrtCoEventUnit函数

释放协程事件;仍有尚未返回的等待者时失败并保持对象有效。

bool xrtCoEventUnit(xcoevent* pEvent)

参数

参数方向约束说明
pEvent输入非空Init 产物;与其他操作不能并发
返回值
返回含义失败时状态
true固定存储已释放—
false仍有 Await 未返回对象保持有效;XERR_STATE
错误
  • XERR_ARGUMENT — 指针为空
  • XERR_STATE — 仍有等待者(即使已获信号)

范例已编译验证

concurrency/coroutine_event · 收尾 · 排空后释放

(void)xrtCoSchedDestroy(pSched);
(void)xrtCoEventUnit(&tEvent);
(void)xrtCoThreadDetach();

xrtCoEventCreate函数

创建自动或手动复位协程事件(堆存储易用层)。

xcoevent* xrtCoEventCreate(bool bManualReset, bool bSignaled)

参数

参数方向约束说明
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 返回的协程事件;仍有等待者时失败且不释放对象。

bool xrtCoEventDestroy(xcoevent* pEvent)

参数

参数方向约束说明
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 唤醒一个。

bool xrtCoEventSet(xcoevent* pEvent)

参数

参数方向约束说明
pEvent输入非空目标事件;线程安全
返回值
返回含义失败时状态
true已置位并投递唤醒—
false指针非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空

范例已编译验证

concurrency/coroutine_event · 生产者 · 短睡后置位事件

return xrtCoEventSet(pEvent) ? pEvent : NULL;

xrtCoEventReset函数

清除事件的信号态;已经获得信号的等待者不受影响。

bool xrtCoEventReset(xcoevent* pEvent)

参数

参数方向约束说明
pEvent输入非空目标事件
返回值
返回含义失败时状态
true后续等待不再看到信号—
false指针非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空

范例已编译验证

concurrency/coroutine_tour · 事件族 · 双 Set 后清信号覆盖

(void)xrtCoEventReset(pJob->pAuto);  /* 清信号(覆盖点) */

xrtCoEventAwait函数

挂起当前调度协程,直到事件置位或协程取消。

xwaitresult xrtCoEventAwait(xcoevent* pEvent)

参数

参数方向约束说明
pEvent输入非空目标事件
返回值
返回含义失败时状态
XWAIT_OK取得信号(自动复位信号被消费)—
XWAIT_CANCELLED协程被取消—
XWAIT_ERROR非调度协程或终结过程内XERR_STATE
错误
  • XERR_ARGUMENT — 指针为空
  • XERR_STATE — 非调度协程,或终结过程中调用

范例已编译验证

concurrency/coroutine_event · 消费者 · 等待生产者置位

if ( xrtCoEventAwait(pEvent) != XWAIT_OK ) {

xrtCoEventTryAwait函数

非阻塞地检查并消费自动复位事件。

xwaitresult xrtCoEventTryAwait(xcoevent* pEvent)

参数

参数方向约束说明
pEvent输入非空目标事件
返回值
返回含义失败时状态
XWAIT_OK有信号并已消费(自动复位)—
XWAIT_TIMEOUT无信号(正常结果)不设错
XWAIT_CANCELLED已取消—
XWAIT_ERROR参数/状态错误错误经 xrtGetError() 报告
错误
  • 同 xrtCoEventAwait

范例已编译验证

concurrency/coroutine_tour · 事件族 · 预置位立即消费

if ( xrtCoEventTryAwait(pJob->pAuto) == XWAIT_OK ) {

xrtCoEventAwaitFor函数

在相对毫秒数内等待事件置位。

xwaitresult xrtCoEventAwaitFor(xcoevent* pEvent, int64 iTimeout)

参数

参数方向约束说明
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见头文件注释