# 信号量
***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 。