模块契约Sync
存储与所有权
每种对象都是 8 字节对齐的固定存储 union,可嵌入结构、放在栈上或批量分配。 XRT_MUTEX_STORAGE_SIZE、XRT_COND_STORAGE_SIZE、XRT_SEM_STORAGE_SIZE、 XRT_RWLOCK_STORAGE_SIZE 和 XRT_EVENT_STORAGE_SIZE 是对应公共存储大小。 平台内部布局有编译期越界检查。
所有对象提供两种生命周期:
Init/Unit 初始化和释放调用方提供的存储,不产生堆分配。Create/Destroy 分配和释放对象,适合普通拥有式用法。
Init 只能用于尚未初始化或已经成功 Unit 的存储,不能覆盖仍有效的对象。 Unit/Destroy 时不得还有持有者、等待者或并发调用者。Destroy(NULL) 成功且无操作。
错误口径
等待函数返回 xwaitresult。竞争、超时和尚未触发属于正常控制流,不设置错误; 无效参数、未初始化对象、所有权错误和平台失败会设置结构化 xrt.sync 错误。 返回 bool 的函数失败后,可通过 xrtErrorGet() 或 xrtGetError() 取得详情。
基础可运行示例见 examples/concurrency/sync/main.c、condition/main.c、 semaphore/main.c 和 rwlock/main.c。每种原语的跨线程、超时、 多等待者、错误状态和 OOM 边界见 tests/concurrency/test_mutex.c、 test_cond.c、test_sem.c、test_rwlock.c、test_event.c 和 test_sync_oom.c。
裁剪与依赖
| 能力 | 启用宏 | 依赖 |
|---|
| 公共同步底座 | XRT_FEATURE_SYNC | core |
| Mutex | XRT_FEATURE_MUTEX | sync |
| Condition | XRT_FEATURE_COND | mutex、wait |
| Semaphore | XRT_FEATURE_SEM | sync、wait |
| RWLock | XRT_FEATURE_RWLOCK | sync |
| Event | XRT_FEATURE_EVENT | sync、wait |
Mutex
xmutex 是非递归独占锁。递归锁定和非持有者解锁失败并设置状态错误; TryLock 因其他线程持有锁而返回 false 时不设置错误。
| 函数 | 说明 |
|---|
xrtMutexInit(pMutex) | 初始化调用方存储。 |
xrtMutexUnit(pMutex) | 释放平台资源;锁仍被持有时失败。 |
xrtMutexCreate() | 创建 mutex,失败返回 NULL。 |
xrtMutexDestroy(pMutex) | 释放拥有式 mutex。 |
xrtMutexLock(pMutex) | 阻塞到当前线程获得锁。 |
xrtMutexTryLock(pMutex) | 非阻塞尝试获得锁。 |
xrtMutexUnlock(pMutex) | 由持有线程释放锁。 |
Condition
xcond 必须与 xmutex 配合。等待会原子释放 mutex,返回前重新获得 mutex。 通知不保存状态,因此必须始终在受 mutex 保护的谓词循环中等待。 调用等待函数时,当前线程必须已经持有传入的 mutex;否则返回 XWAIT_ERROR 并设置 XERR_STATE。在满足此前置条件时,等待无论因通知、超时还是平台错误返回,当前线程 仍持有 mutex。
| 函数 | 说明 |
|---|
xrtCondInit(pCond) | 初始化调用方存储。 |
xrtCondUnit(pCond) | 释放平台资源。 |
xrtCondCreate() | 创建 condition。 |
xrtCondDestroy(pCond) | 释放拥有式 condition。 |
xrtCondWait(pCond, pMutex) | 无限等待通知。 |
xrtCondWaitFor(pCond, pMutex, iTimeout) | 最多等待相对毫秒数。 |
xrtCondWaitFor(pCond, pMutex, iDeadline) | 等待到绝对单调 deadline。 |
xrtCondSignal(pCond) | 唤醒一个当前等待者。 |
xrtCondBroadcast(pCond) | 唤醒全部当前等待者。 |
修改谓词的线程应在同一 mutex 内更新状态,再调用 Signal 或 Broadcast。 条件变量允许虚假唤醒,通知也不会保存为可供未来等待者消费的状态。因此 Wait、WaitFor 和 WaitUntil 只能放在受同一 mutex 保护的谓词循环中;返回 XWAIT_OK 只表示线程已经重新取得 mutex,不表示谓词必然成立。
Semaphore
xsem 是范围统一为 [0, INT32_MAX] 的计数信号量。等待成功会消费一个计数。 PostMany 是全有或全无操作,超过最大值时原计数不变。
| 函数 | 说明 |
|---|
xrtSemInit(pSem, iInitial, iMaximum) | 初始化有界计数;最大值必须非零且不超过 INT32_MAX。 |
xrtSemUnit(pSem) | 释放平台资源。 |
xrtSemCreate(iInitial, iMaximum) | 创建 semaphore。 |
xrtSemDestroy(pSem) | 释放拥有式 semaphore。 |
xrtSemWait(pSem) | 无限等待并消费一个计数。 |
xrtSemTryWait(pSem) | 非阻塞尝试消费,空时返回 XWAIT_TIMEOUT。 |
xrtSemWaitFor(pSem, iTimeout) | 在相对毫秒数内等待。 |
xrtSemWaitFor(pSem, iDeadline) | 等待到绝对单调 deadline。 |
xrtSemPost(pSem) | 发布一个计数。 |
xrtSemPostMany(pSem, iCount) | 原子发布多个计数;0 成功且无操作。 |
RWLock
xrwlock 允许多个读者或一个写者,并采用写者优先策略,避免持续读流量饿死写者。 写锁记录持有线程,拒绝递归写、非持有者释放和非法降级。
| 函数 | 说明 |
|---|
xrtRWLockInit(pLock) | 初始化调用方存储。 |
xrtRWLockUnit(pLock) | 无持有者和等待者时释放平台资源。 |
xrtRWLockCreate() | 创建 RWLock。 |
xrtRWLockDestroy(pLock) | 释放拥有式 RWLock。 |
xrtRWLockRead(pLock) | 获得共享读锁。 |
xrtRWLockTryRead(pLock) | 无写者或等待写者时尝试获得读锁。 |
xrtRWLockReadUnlock(pLock) | 释放调用方持有的一个读锁。 |
xrtRWLockWrite(pLock) | 获得独占写锁。 |
xrtRWLockTryWrite(pLock) | 无读者和写者时尝试获得写锁。 |
xrtRWLockWriteUnlock(pLock) | 由写持有线程释放写锁。 |
xrtRWLockDowngrade(pLock) | 原子把当前写锁降级成一个读锁。 |
xrtRWLockUpgrade(pLock) | 释放调用方的一个读锁并排队获得写锁。 |
读锁不维护每线程所有权表,以保持读路径紧凑。调用方必须只释放自己持有的读锁; 读锁是非递归的,同一线程不得在释放前再次获取。调用 Upgrade 时必须确实持有且只 持有一个读锁。Upgrade 先释放该读锁再进入写者队列, 因此多个升级者不会彼此保留读锁而死锁。
Event
xevent 保存显式信号状态。自动复位事件的一次信号只释放一个等待者;没有等待者时 保留一个信号。手动复位事件在 Reset 前保持有信号并释放全部等待者。
| 函数 | 说明 |
|---|
xrtEventInit(pEvent, bManualReset, bSignaled) | 初始化事件并指定复位方式和初始状态。 |
xrtEventUnit(pEvent) | 释放平台资源。 |
xrtEventCreate(bManualReset, bSignaled) | 创建事件。 |
xrtEventDestroy(pEvent) | 释放拥有式事件。 |
xrtEventWait(pEvent) | 无限等待信号。 |
xrtEventTryWait(pEvent) | 非阻塞检查;自动复位事件成功时消费信号。 |
xrtEventWaitFor(pEvent, iTimeout) | 在相对毫秒数内等待。 |
xrtEventWaitFor(pEvent, iDeadline) | 等待到绝对单调 deadline。 |
xrtEventSet(pEvent) | 设置有信号状态并按复位方式唤醒等待者。 |
xrtEventReset(pEvent) | 清除有信号状态。 |
Event 适合完成通知、一次性闸门和取消唤醒;由共享数据决定的复杂条件应使用 mutex、condition 和谓词循环。
xmutex类型
Mutex 使用固定对齐存储,允许嵌入用户结构且不暴露平台头。
| 字段 | 类型 | 语义 |
|---|
Alignment | uint64 | 对齐(二次幂) |
typedef union xmutex { uint64 Alignment; uint8 Storage[XRT_MUTEX_STORAGE_SIZE]; } xmutex;
xcond类型
条件变量必须和 XRT mutex 配合使用。
| 字段 | 类型 | 语义 |
|---|
Alignment | uint64 | 对齐(二次幂) |
typedef union xcond { uint64 Alignment; uint8 Storage[XRT_COND_STORAGE_SIZE]; } xcond;
xsem类型
信号量的计数范围在所有平台统一为 [0, INT32_MAX]。
| 字段 | 类型 | 语义 |
|---|
Alignment | uint64 | 对齐(二次幂) |
typedef union xsem { uint64 Alignment; uint8 Storage[XRT_SEM_STORAGE_SIZE]; } xsem;
xrwlock类型
读写锁采用写者优先策略并支持升级和降级。
| 字段 | 类型 | 语义 |
|---|
Alignment | uint64 | 对齐(二次幂) |
typedef union xrwlock { uint64 Alignment; uint8 Storage[XRT_RWLOCK_STORAGE_SIZE]; } xrwlock;
xevent类型
事件保存显式信号状态,可选择自动或手动复位。
| 字段 | 类型 | 语义 |
|---|
Alignment | uint64 | 对齐(二次幂) |
typedef union xevent { uint64 Alignment; uint8 Storage[XRT_EVENT_STORAGE_SIZE]; } xevent;
Mutex
xrtMutexInit函数
初始化调用方存储中的非递归互斥锁。
bool xrtMutexInit(xmutex* pMutex)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已初始化 | — |
false | 参数非法 | XERR_ARGUMENT |
错误XERR_ARGUMENT — 指针为空或参数非法
范例已编译验证
sync · 初始化
if ( !xrtMutexInit(&tMutex) ) {
xrtMutexUnit函数
释放互斥锁平台资源;仍被持有时失败且保持对象有效。
bool xrtMutexUnit(xmutex* pMutex)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pMutex | 输入 | 非空、未持有 | 目标互斥锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 仍被持有 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync · 释放平台资源
(void)xrtMutexUnit(&tMutex);
xrtMutexCreate函数
创建一个非递归互斥锁。
xmutex* xrtMutexCreate()
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 非空 | 互斥锁 | — |
NULL | 分配或初始化失败 | XERR_MEMORY 等 |
范例已编译验证
sync_tour · 堆创建
pMutex = xrtMutexCreate();
xrtMutexDestroy函数
释放 Create 返回的互斥锁;仍被持有时失败且不释放对象。
bool xrtMutexDestroy(xmutex* pMutex)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pMutex | 输入 | 非空、未持有 | 目标互斥锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已销毁 | — |
false | 仍被持有 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 销毁
xrtMutexDestroy(pMutex);
xrtMutexLock函数
阻塞到获得互斥锁;同线程递归加锁返回错误。
bool xrtMutexLock(xmutex* pMutex)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pMutex | 输入 | 非空、未由本线程持有 | 目标互斥锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有 | — |
false | 递归加锁或状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 同线程递归加锁
范例已编译验证
sync_tour · 加锁
(void)xrtMutexLock(pJob->pMutex);
xrtMutexTryLock函数
尝试获得互斥锁;锁正忙时返回 false 且不设置错误。
bool xrtMutexTryLock(xmutex* pMutex)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有 | — |
false | 正忙 | 不设错误 |
错误- 正忙返回
false 且不设置错误;参数非法 XERR_ARGUMENT
范例已编译验证
sync_tour · 尝试加锁
xrtMutexTryLock(pMutex) || /* 已持有:Try 必失败 */
xrtMutexUnlock函数
释放当前线程持有的互斥锁。
bool xrtMutexUnlock(xmutex* pMutex)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pMutex | 输入 | 非空、本线程持有 | 目标互斥锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 未持有 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 解锁
(void)xrtMutexUnlock(pJob->pMutex);
Condition
xrtCondInit函数
初始化调用方存储中的条件变量。
bool xrtCondInit(xcond* pCond)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已初始化 | — |
false | 参数非法 | XERR_ARGUMENT |
错误XERR_ARGUMENT — 指针为空或参数非法
范例已编译验证
condition · 初始化
if ( !xrtCondInit(&Cond) ) {
xrtCondUnit函数
释放条件变量平台资源。
bool xrtCondUnit(xcond* pCond)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
condition · 释放平台资源
(void)xrtCondUnit(&Cond);
xrtCondCreate函数
创建条件变量。
xcond* xrtCondCreate()
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 非空 | 条件变量 | — |
NULL | 分配失败 | XERR_MEMORY 等 |
范例已编译验证
sync_tour · 堆创建
pCond = xrtCondCreate();
xrtCondDestroy函数
释放 Create 返回的条件变量。
bool xrtCondDestroy(xcond* pCond)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已销毁 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 销毁
xrtCondDestroy(pCond);
xrtCondWait函数
当前线程持有 mutex 时原子释放并等待;允许虚假唤醒,必须在谓词循环中调用。
xwaitresult xrtCondWait(xcond* pCond, xmutex* pMutex)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pCond | 输入 | 非空 | 目标条件变量 |
pMutex | 输入 | 非空、本线程持有 | 配对互斥锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 虚假唤醒后的再次超时 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法- 允许虚假唤醒,返回
OK 后仍须循环检查谓词
范例已编译验证
sync_tour · 等待
pJob->iWaitResult = xrtCondWait(pJob->pCond,
pJob->pMutex);
xrtCondWaitFor函数
在相对毫秒数内等待;超时和成功后都重新持有 mutex。
xwaitresult xrtCondWaitFor(xcond* pCond, xmutex* pMutex, int64 iTimeout)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pCond | 输入 | 非空 | 目标条件变量 |
pMutex | 输入 | 非空、本线程持有 | 配对互斥锁 |
iTimeout | 输入 | — | 相对毫秒数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 期限或截止时间先到达 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法- 允许虚假唤醒,应循环检查受 mutex 保护的谓词
范例已编译验证
sync_tour · 限时等待
pJob->iForResult = xrtCondWaitFor(pJob->pCond, pJob->pMutex,
EXAMPLE_TIMEOUT_MS); /* 无人 Signal:到期 */
xrtCondSignal函数
唤醒一个等待者;通知本身不保存状态。
bool xrtCondSignal(xcond* pCond)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已发出通知 | — |
false | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 唤醒一个
(void)xrtCondSignal(pCond);
xrtCondBroadcast函数
唤醒全部当前等待者;通知本身不保存状态。
bool xrtCondBroadcast(xcond* pCond)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已发出通知 | — |
false | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
condition · 唤醒全部
if ( !xrtCondSignal(&Cond) || !xrtCondBroadcast(&Cond) ||
!xrtMutexLock(&Mutex) ) {
Semaphore
xrtSemInit函数
初始化计数信号量。
bool xrtSemInit(xsem* pSem, uint32 iInitial, uint32 iMaximum)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pSem | 输出 | 非空 | 接收信号量 |
iInitial | 输入 | <= iMaximum | 初始计数 |
iMaximum | 输入 | > 0 | 最大计数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已初始化 | — |
false | 参数非法 | XERR_ARGUMENT |
错误XERR_ARGUMENT — 指针为空或参数非法
范例已编译验证
semaphore · 初始化
if ( !xrtSemInit(&Semaphore, 0, 1) ||
!xrtSemPost(&Semaphore) ) {
xrtSemUnit函数
释放信号量平台资源。
bool xrtSemUnit(xsem* pSem)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
semaphore · 释放平台资源
return xrtSemUnit(&Semaphore) &&
xrtSemCreate函数
创建计数信号量。
xsem* xrtSemCreate(uint32 iInitial, uint32 iMaximum)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
iInitial | 输入 | <= iMaximum | 初始计数 |
iMaximum | 输入 | > 0 | 最大计数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 非空 | 信号量 | — |
NULL | 创建失败 | XERR_ARGUMENT / XERR_MEMORY |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_MEMORY — 分配失败
范例已编译验证
sync_tour · 堆创建
pSem = xrtSemCreate(0u, 4u);
xrtSemDestroy函数
释放 Create 返回的信号量。
bool xrtSemDestroy(xsem* pSem)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已销毁 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
xrtSemWait函数
等待并消费一个信号。
xwaitresult xrtSemWait(xsem* pSem)
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 期限或截止时间先到达 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 等待
(xrtSemWait(pSem) != XWAIT_OK) ||
xrtSemTryWait函数
非阻塞地尝试消费一个信号。
xwaitresult xrtSemTryWait(xsem* pSem)
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 已消费一个信号 | — |
XWAIT_TIMEOUT | 当前计数为零 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 尝试等待
(xrtSemTryWait(pSem) != XWAIT_TIMEOUT) ) {
xrtSemWaitFor函数
在相对毫秒数内等待并消费一个信号。
xwaitresult xrtSemWaitFor(xsem* pSem, int64 iTimeout)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pSem | 输入 | 非空 | 目标信号量 |
iTimeout | 输入 | — | 相对毫秒数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 期限或截止时间先到达 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 限时等待
(xrtSemWaitFor(pSem, EXAMPLE_TIMEOUT_MS) != XWAIT_OK) ) {
xrtSemPost函数
发布一个信号;达到上限时失败且计数不变。
bool xrtSemPost(xsem* pSem)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已发布 | — |
false | 达到上限或状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 计数达到上限,计数不变
范例已编译验证
semaphore · 发布
!xrtSemPost(&Semaphore) ) {
xrtSemPostMany函数
原子发布多个信号;超过上限时失败且不部分发布。
bool xrtSemPostMany(xsem* pSem, uint32 iCount)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pSem | 输入 | 非空 | 目标信号量 |
iCount | 输入 | — | 发布数量 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已全部发布 | — |
false | 超过上限 | XERR_STATE,不部分发布 |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 发布后超过上限,计数不变
范例已编译验证
sync_tour · 批量发布
if ( !xrtSemPostMany(pSem, 3u) ||
(xrtSemTryWait(pSem) != XWAIT_OK) ||
(xrtSemWait(pSem) != XWAIT_OK) ||
(xrtSemWaitFor(pSem, EXAMPLE_TIMEOUT_MS) != XWAIT_OK) ) {
RWLock
xrtRWLockInit函数
初始化写者优先的读写锁。
bool xrtRWLockInit(xrwlock* pLock)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已初始化 | — |
false | 参数非法 | XERR_ARGUMENT |
错误XERR_ARGUMENT — 指针为空或参数非法
范例已编译验证
rwlock · 初始化
if ( !xrtRWLockInit(&Lock) ) {
xrtRWLockUnit函数
释放读写锁平台资源;仍被持有或等待时失败。
bool xrtRWLockUnit(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、无持有无等待 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 仍被持有或等待 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
rwlock · 释放平台资源
return xrtRWLockUnit(&Lock) && bOkay && (iValue == 15) ? 0 : 2;
xrtRWLockCreate函数
创建写者优先的读写锁。
xrwlock* xrtRWLockCreate()
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 非空 | 读写锁 | — |
NULL | 分配失败 | XERR_MEMORY 等 |
范例已编译验证
sync_tour · 堆创建
pLock = xrtRWLockCreate();
xrtRWLockDestroy函数
释放 Create 返回的读写锁。
bool xrtRWLockDestroy(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、无持有无等待 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已销毁 | — |
false | 仍被持有或等待 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 销毁
xrtRWLockDestroy(pLock);
xrtRWLockRead函数
获得非递归共享读锁;读锁所有权由调用方保证。
bool xrtRWLockRead(xrwlock* pLock)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有读锁 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 读加锁
!xrtRWLockRead(pLock) ||
xrtRWLockTryRead函数
尝试获得共享读锁;写者存在或等待时返回 false。
bool xrtRWLockTryRead(xrwlock* pLock)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有读锁 | — |
false | 写者存在或等待 | 不设错误 |
错误- 写者存在或等待返回
false 且不设置错误;参数非法 XERR_ARGUMENT
范例已编译验证
rwlock · 尝试读加锁
!xrtRWLockTryRead(&Lock) ) {
xrtRWLockReadUnlock函数
释放当前线程持有的一个读锁。
bool xrtRWLockReadUnlock(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、本线程持有读锁 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 未持有 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 读解锁
!xrtRWLockReadUnlock(pLock) ||
xrtRWLockWrite函数
获得独占写锁。
bool xrtRWLockWrite(xrwlock* pLock)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有写锁 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
rwlock · 写加锁
!xrtRWLockWrite(&Lock) ) {
xrtRWLockTryWrite函数
尝试获得独占写锁。
bool xrtRWLockTryWrite(xrwlock* pLock)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已持有写锁 | — |
false | 存在其他持有者 | 不设错误 |
错误- 存在其他持有者返回
false 且不设置错误;参数非法 XERR_ARGUMENT
范例已编译验证
sync_tour · 尝试写加锁
xrtRWLockTryWrite(pLock) || /* 读持有时写必失败 */
xrtRWLockWriteUnlock函数
释放当前线程持有的写锁。
bool xrtRWLockWriteUnlock(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、本线程持有写锁 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 未持有 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 写解锁
!xrtRWLockWriteUnlock(pLock) ) {
xrtRWLockDowngrade函数
原子地把当前线程的写锁降级为一个读锁。
bool xrtRWLockDowngrade(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、本线程持有写锁 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已降级为读锁 | — |
false | 未持有写锁 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
rwlock · 降级
if ( !xrtRWLockDowngrade(&Lock) ||
!xrtRWLockReadUnlock(&Lock) ||
!xrtRWLockWrite(&Lock) ) {
xrtRWLockUpgrade函数
当前线程只持有一个读锁时,释放它并排队获得写锁。
bool xrtRWLockUpgrade(xrwlock* pLock)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pLock | 输入 | 非空、本线程恰好持有一个读锁 | 目标读写锁 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已升级为写锁 | — |
false | 持有数不是一或状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 当前线程持有的读锁数量不是恰好一个
范例已编译验证
rwlock · 升级
!xrtRWLockUpgrade(&Lock) ) {
Event
xrtEventInit函数
初始化自动或手动复位事件。
bool xrtEventInit(xevent* pEvent, bool bManualReset, bool bSignaled)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pEvent | 输出 | 非空 | 接收事件 |
bManualReset | 输入 | — | 手动复位 |
bSignaled | 输入 | — | 初始信号态 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已初始化 | — |
false | 参数非法 | XERR_ARGUMENT |
错误XERR_ARGUMENT — 指针为空或参数非法
范例已编译验证
sync_tour · 初始化
if ( !xrtEventInit(&tManual, true, false) ) {
xrtEventUnit函数
释放事件平台资源。
bool xrtEventUnit(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已释放 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 释放平台资源
xrtEventUnit(&tManual);
xrtEventCreate函数
创建自动或手动复位事件。
xevent* xrtEventCreate(bool bManualReset, bool bSignaled)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
bManualReset | 输入 | — | 手动复位 |
bSignaled | 输入 | — | 初始信号态 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 非空 | 事件 | — |
NULL | 创建失败 | XERR_ARGUMENT / XERR_MEMORY |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_MEMORY — 分配失败
范例已编译验证
sync_tour · 堆创建
pAuto = xrtEventCreate(false, false);
xrtEventDestroy函数
释放 Create 返回的事件。
bool xrtEventDestroy(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已销毁 | — |
false | 状态非法 | XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 销毁
xrtEventDestroy(pAuto);
xrtEventWait函数
等待事件进入信号态。
xwaitresult xrtEventWait(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 不会发生(无限等待) | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法- 自动复位事件等到即消费信号
范例已编译验证
sync_tour · 等待
(xrtEventWait(&tManual) != XWAIT_OK) ||
xrtEventTryWait函数
非阻塞地检查并消费自动复位事件。
xwaitresult xrtEventTryWait(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 已等到并消费 | — |
XWAIT_TIMEOUT | 未处于信号态 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 尝试等待
(xrtEventTryWait(pAuto) != XWAIT_TIMEOUT) ||
xrtEventWaitFor函数
在相对毫秒数内等待事件。
xwaitresult xrtEventWaitFor(xevent* pEvent, int64 iTimeout)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
pEvent | 输入 | 非空 | 目标事件 |
iTimeout | 输入 | — | 相对毫秒数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
XWAIT_OK | 获得/等到 | — |
XWAIT_TIMEOUT | 期限或截止时间先到达 | 不设错误 |
XWAIT_ERROR | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 限时等待
(xrtEventWaitFor(pAuto, EXAMPLE_TIMEOUT_MS) !=
XWAIT_TIMEOUT) ) {
xrtEventSet函数
设置事件;手动复位唤醒全部等待者,自动复位唤醒一个等待者。
bool xrtEventSet(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已置位 | — |
false | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 置位
!xrtEventSet(pAuto) ||
xrtEventReset函数
清除事件信号态。
bool xrtEventReset(xevent* pEvent)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 已清除 | — |
false | 参数或状态非法 | XERR_ARGUMENT / XERR_STATE |
错误XERR_ARGUMENT — 指针为空或参数非法XERR_STATE — 对象仍被持有、等待或状态非法
范例已编译验证
sync_tour · 复位
!xrtEventReset(&tManual) ||
常量索引常量
以下常量在本页所属头文件中定义,语义见公共头注释。
| 常量 | 说明 |
| XRT_COND_STORAGE_SIZE | 见头文件注释 |
| XRT_EVENT_STORAGE_SIZE | 见头文件注释 |
| XRT_MUTEX_STORAGE_SIZE | 见头文件注释 |
| XRT_RWLOCK_STORAGE_SIZE | 见头文件注释 |
| XRT_SEM_STORAGE_SIZE | 见头文件注释 |