semaphore
semaphore 提供 POSIX 信号量功能,支持无名信号量和有名信号量的创建、等待、释放与销毁操作,用于线程间同步与资源计数。
头文件清单
接口清单
| 接口名称 | 功能简述 |
|---|---|
| sem_close | 关闭有名信号量 |
| sem_destroy | 销毁无名信号量 |
| sem_getvalue | 获取指定信号量的值 |
| sem_init | 初始化无名信号量 |
| sem_open | 打开或创建有名信号量 |
| sem_post | 释放一个指定的无名信号量 |
| sem_timedwait | 申请一个超时等待的无名信号量 |
| sem_trywait | 尝试申请一个无名信号量 |
| sem_unlink | 删除有名信号量 |
| sem_wait | 申请等待一个无名信号量 |
Functions
sem_close
头文件清单
功能说明
- 关闭一个有名信号量,减少其引用计数
- 当引用计数降为0且信号量已被sem_unlink删除时,释放信号量资源
- 当前LiteOS实现中此接口返回ENOSYS,不支持有名信号量操作
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向待关闭的有名信号量结构体的指针 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 关闭成功 | 有名信号量关闭成功 |
| -1 | 关闭失败 | sem为NULL或semHandle无效(EINVAL)或当前平台不支持(ENOSYS) |
sem_destroy
头文件清单
功能说明
- 销毁一个已初始化的无名信号量,释放其占用的系统资源
- 销毁后信号量不可再使用,除非重新调用sem_init初始化
- 若有其他线程正在等待该信号量,销毁操作将失败
前置条件
- 调用时序约束:当前接口必须在信号量通过sem_init成功初始化后调用
- 依赖关系:确保没有其他线程正在等待该信号量
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向待销毁的无名信号量结构体的指针 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 销毁成功 | 信号量销毁成功 |
| -1 | 销毁失败 | sem为NULL或sem->sem为NULL(EINVAL)或有线程正在等待该信号量(EBUSY) |
sem_getvalue
头文件清单
功能说明
- 获取指定无名信号量的当前值
- 将信号量当前值写入currVal指向的整型变量中
- 该操作不会修改信号量的值
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t *__restrict | 指向目标无名信号量结构体的指针 | 非NULL |
出参
| 名称 | 数据类型 | 输出说明 |
|---|---|---|
| currVal | int *__restrict | 输出信号量的当前计数值 |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 获取成功 | 成功获取信号量当前值 |
| -1 | 获取失败 | sem为NULL或sem->sem为NULL或currVal为NULL(EINVAL) |
sem_init
头文件清单
功能说明
- 初始化一个无名信号量,将其值设置为指定的初始值
- shared参数在当前实现中未使用,进程间共享信号量不被支持
- 初始值不能超过SEM_VALUE_MAX
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向待初始化的无名信号量结构体的指针 | 非NULL |
| shared | int | 共享标志,指示信号量是否在进程间共享 | 当前实现中该参数未使用 |
| value | unsigned | 信号量的初始值 | 0 ~ SEM_VALUE_MAX |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 初始化成功 | 信号量初始化成功 |
| -1 | 初始化失败 | sem为NULL或value超过SEM_VALUE_MAX(EINVAL)或信号量资源不足(ENOSPC) |
sem_open
头文件清单
功能说明
- 打开或创建一个有名信号量
- 若指定名称的有名信号量已存在,则增加引用计数并返回该信号量指针
- 若指定名称的有名信号量不存在且flags包含O_CREAT标志,则创建新的有名信号量
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| name | const char * | 有名信号量的名称 | 非NULL,长度小于OS_SEM_NAME_LEN |
| flags | int | 打开标志,如O_CREAT、O_EXCL等 | 合法的打开标志组合 |
| ... | 可变参数 | 当flags包含O_CREAT时,依次为mode(unsigned int,权限模式)和value(unsigned int,初始值) | mode未使用;value范围 0 ~ OS_SEM_COUNT_MAX |
返回值
- 返回类型:sem_t *
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 非SEM_FAILED指针 | 打开/创建成功 | 有名信号量打开或创建成功 |
| SEM_FAILED | 打开/创建失败 | name无效或flags无效(EINVAL)或信号量已存在且指定O_CREAT与O_EXCL(EEXIST)或信号量不存在且未指定O_CREAT(ENOENT)或当前平台不支持(ENOSYS) |
sem_post
头文件清单
功能说明
- 释放一个无名信号量,将信号量的值加1
- 若有其他线程正在等待该信号量,则唤醒其中一个等待线程
- 信号量值递增后不能超过SEM_VALUE_MAX
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向目标无名信号量结构体的指针 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 释放成功 | 信号量值成功加1 |
| -1 | 释放失败 | sem为NULL或sem->sem为NULL(EINVAL)或信号量值溢出(ENOSPC) |
sem_timedwait
头文件清单
功能说明
- 在指定的超时时间内等待申请一个无名信号量,将信号量的值减1
- 若信号量当前值大于0,则立即返回成功
- 若信号量当前值为0,则阻塞调用线程直到信号量值大于0或超时
前置条件
- 调用时序约束:当前接口必须在信号量通过sem_init成功初始化后调用
- 调用上下文约束:当前接口会阻塞调用线程,禁止在中断上下文调用
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t *__restrict | 指向目标无名信号量结构体的指针 | 非NULL |
| timeout | const struct timespec *__restrict | 指向超时时间结构体的指针 | 非NULL,tv_nsec取值范围 0 ~ 999999999 |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 申请成功 | 在超时时间内信号量值大于0,成功减1 |
| -1 | 申请失败 | sem为NULL或timeout无效(EINVAL)或超时(ETIMEDOUT)或被信号中断(EINTR) |
sem_trywait
头文件清单
功能说明
- 尝试申请一个无名信号量,将信号量的值减1
- 若信号量当前值大于0,则立即返回成功
- 若信号量当前值为0,则立即返回失败,不阻塞调用线程
前置条件
- 调用时序约束:当前接口必须在信号量通过sem_init成功初始化后调用
- 运行上下文限制:当前接口为非阻塞操作,可在中断上下文调用
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向目标无名信号量结构体的指针 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 申请成功 | 信号量值大于0,成功减1 |
| -1 | 申请失败 | sem为NULL或sem->sem为NULL(EINVAL)或信号量值为0(EAGAIN) |
sem_unlink
头文件清单
功能说明
- 删除一个有名信号量的名称
- 若信号量当前无引用则立即销毁,若有引用则退化为无名信号量继续使用
- 当前LiteOS实现中此接口返回ENOSYS,不支持有名信号量操作
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| name | const char * | 有名信号量的名称 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 删除成功 | 有名信号量名称删除成功 |
| -1 | 删除失败 | name为NULL(EINVAL)或指定名称的信号量不存在(ENOENT)或当前平台不支持(ENOSYS) |
sem_wait
头文件清单
功能说明
- 申请(等待)一个无名信号量,将信号量的值减1
- 若信号量当前值大于0,则立即返回成功
- 若信号量当前值为0,则阻塞调用线程直到信号量值大于0
前置条件
- 调用时序约束:当前接口必须在信号量通过sem_init成功初始化后调用
- 调用上下文约束:当前接口会阻塞调用线程,禁止在中断上下文调用
入参
| 名称 | 参数类型 | 详细说明 | 约束取值范围 |
|---|---|---|---|
| sem | sem_t * | 指向目标无名信号量结构体的指针 | 非NULL |
返回值
- 返回类型:int
| 返回值 | 文字含义 | 触发场景 |
|---|---|---|
| 0 | 申请成功 | 信号量值大于0,成功减1 |
| -1 | 申请失败 | sem为NULL或sem->sem为NULL(EINVAL)或被信号中断(EINTR) |
Structures
posix_sem
#ifdef LOSCFG_BOX
#define LITEOS_SEMAPHORE_SEM unsigned long semId
#else
#define LITEOS_SEMAPHORE_SEM void *sem
#endif
typedef struct posix_sem {
LITEOS_SEMAPHORE_SEM;
} sem_t;
成员说明
| 成员名称 | 数据类型 | 描述 |
|---|---|---|
| sem | void * | LiteOS信号量控制块指针(非LOSCFG_BOX配置时生效) |
| semId | unsigned long | LiteOS信号量ID(LOSCFG_BOX配置时生效) |