# 信号量 ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # 功能概述 信号量(semaphore)是一个同步对象,其计数值在0到指定的最大值之间。当线程完成一次对信号量对象的等待时,信号量计数值减一;当线程完成一次对信号量对象的释放时,信号量计数值加一。 通过信号量可以控制多线程的执行顺序。例如,当多个线程对资源的操作存在先后依赖关系时(即某个线程必须优先执行,其他线程才能继续处理),可以使用信号量进行协调。 # 信号量API ## 头文件 *qosa_sys.h* ## 函数概览 | **函数** | **说明** | | --- | --- | | *qosa_sem_create()* | 创建计数信号量(最大计数值为系统上限) | | *qosa_sem_create_ex()* | 创建可指定最大计数值的信号量 | | *qosa_sem_wait()* | 等待信号量(支持超时设置) | | *qosa_sem_get_cnt()* | 获取当前信号量的计数值 | | *qosa_sem_release()* | 释放信号量 | | *qosa_sem_delete()* | 删除信号量 | ## 函数详解 ### qosa_sem_create - **功能描述** 创建计数信号量(最大计数值为系统上限),并将初始值设为 *initialCount*。 - **函数原型** ```c int qosa_sem_create(qosa_sem_t* semaRef, qosa_uint32_t initialCount) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输出 | qosa_sem_t* | 指向信号量句柄的指针 | | *initialCount* | 输入 | qosa_uint32_t | 初始计数值。*initialCount* 必须小于等于 *max_cnt* | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 *QOSA_ERROR_SEMA_CREATE_ERR*:信号量创建失败 ### qosa_sem_create_ex - **功能描述** 创建可指定最大计数值的信号量 **。** - **函数原型** ```c int qosa_sem_create_ex(qosa_sem_t* semaRef, qosa_uint32_t initialCount, qosa_uint32_t max_cnt) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输出 | qosa_sem_t* | 指向信号量句柄的指针 | | *initialCount* | 输入 | qosa_uint32_t | 初始计数值。*initialCount* 必须小于等于 *max_cnt* | | *max_cnt* | 输入 | qosa_uint32_t | 最大计数值 | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 *QOSA_ERROR_SEMA_CREATE_ERR*:信号量创建失败 ### qosa_sem_wait - **功能描述** 等待信号量(支持超时设置)。 - **函数原型** ```c int qosa_sem_wait(qosa_sem_t semaRef, qosa_uint32_t timeout) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输入 | qosa_sem_t | 信号量句柄 | | *timeout* | 输入 | qosa_uint32_t | 超时时间。单位:毫秒
*QOSA_WAIT_FOREVER*:无限等待
*QOSA_NO_WAIT*:不等待 | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 *QOSA_ERROR_SEMA_TIMEOUT_ERR*:等待信号量超时,未获取到有效信号量 ### qosa_sem_get_cnt - **功能描述** 获取当前信号量的计数值。 - **函数原型** ```c int qosa_sem_get_cnt(qosa_sem_t semaRef, qosa_uint32_t* cnt_ptr) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输入 | qosa_sem_t | 信号量句柄 | | *cnt_ptr* | 输出 | qosa_uint32_t* | 用于存储计数值的指针 | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 ### qosa_sem_release - **功能描述** 释放信号量,使其计数值加一。 - **函数原型** ```c int qosa_sem_release(qosa_sem_t semaRef) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输入 | qosa_sem_t | 信号量句柄 | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 *QOSA_ERROR_SEMA_RELEASE_ERR*:信号量释放失败 ### qosa_sem_delete - **功能描述** 删除信号量,并释放资源。 - **函数原型** ```c int qosa_sem_delete(qosa_sem_t semaRef) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *semaRef* | 输入 | qosa_sem_t | 信号量句柄 | - **返回值说明** *QOSA_ERROR_OK*:函数执行成功 *QOSA_ERROR_SEMA_INVALID_ERR*:信号量参数无效 *QOSA_ERROR_SEMA_DELETE_ERR*:信号量删除失败 ## 枚举定义 ### qosa_errcode_os_e 结果码枚举定义如下: ```c typedef enum { QOSA_ERROR_OK = 0, ... QOSA_ERROR_SEMA_CREATE_ERR = 200 | QOSA_ERRCODE_OS_BASE, QOSA_ERROR_SEMA_TIMEOUT_ERR, QOSA_ERROR_SEMA_INVALID_ERR, QOSA_ERROR_SEMA_DELETE_ERR, QOSA_ERROR_SEMA_RELEASE_ERR, ... }qosa_errcode_os_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_ERROR_OK* | 函数执行成功 | | *QOSA_ERROR_SEMA_CREATE_ERR* | 信号量创建失败 | | *QOSA_ERROR_SEMA_TIMEOUT_ERR* | 等待信号量超时,未获取到有效信号量 | | *QOSA_ERROR_SEMA_INVALID_ERR* | 信号量参数无效 | | *QOSA_ERROR_SEMA_DELETE_ERR* | 信号量删除失败 | | *QOSA_ERROR_SEMA_RELEASE_ERR* | 信号量释放失败 | # 应用逻辑流程图 ```{figure} images/board_AS1qwjeZ0hpDgnblPFycRx0snZc.jpg :align: center :alt: image ``` # 示例代码 完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/sync_comm/semaphore/semaphore_demo.c 。