目录
计数型信号量
计数型信号量通常用于多个线程共享使用某资源。
下图显示了SylixOS计数型信号量的基本操作函数在线程与线程之间、中断与线程之间的操作过程。
![](https://img-blog.csdnimg.cn/20200915094431307.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xpYW5ncmVuXw==,size_16,color_FFFFFF,t_70)
1.Create
一个 SylixOS 计数型信号量可以调用 Lw_SemaphoreC_Create 函数进行创建。
#include <SylixOS.h>
LW_HANDLE Lw_SemaphoreC_Create(CPCHAR pcName,
ULONG ulInitCounter,
ULONG ulMaxCounter,
ULONG ulOption,
LW_OBJECT_ID *pulId);
函数 Lw_SemaphoreC_Create 原型分析:
- 此函数成功返回计数型信号量的句柄,失败时返回 NULL 并设置错误号;
- 参数 pcName 是计数型信号量的名字;
- 参数 ulInitCounter 是计数型信号量的初始值;
- 参数 ulMaxCounter 是计数型信号量的最大值;
- 参数 ulOption 是计数型信号量的创建选项如表 7.2 所示;
- 输出参数 pulId 返回计数型信号量的 ID(同返回值),可以为 NULL
计数型信号量的取值范围为 0 <= 计数值(ulInitCounter)< ulMaxCounter(SylixOS 支持的最大计数型信号量值为 4294967295)。特殊地,如果 ulInitCounter 的值为 0,则可以应用于多线程间的同步。
2.Delete
一个不再使用的计数型信号量,可以调用以下函数将其删除。删除后的信号量系统自动,回收其占用的系统资源(试图使用被删除的计数型信号量将出现未知的错误)。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Delete(LW_HANDLE *pulId);
函数 Lw_SemaphoreC_Delete 原型分析:
- 此函数成功返回 0,失败返回错误号;
- 参数 pulId 是计数型信号量的句柄。
3.Wait
线程如果需要等待一个计数型信号量,可以调用 Lw_SemaphoreC_Wait 函数
需要注意的是,中断服务程序不能调用 Lw_SemaphoreC_Wait 函数等待一个计数型信号量,因为Lw_SemaphoreC_Wait 函数在计数型信号量值为 0(线程同步功能)时会阻塞当前线程。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Wait(LW_HANDLE ulId, ULONG ulTimeout);
ULONG Lw_SemaphoreC_TryWait(LW_HANDLE ulId);
以上两个函数原型分析:
- 函数成功返回 0,失败返回错误号;
- 参数 ulId 是计数型信号量的句柄;
- 参数 ulTimeout 是等待的超时时间,单位为时钟嘀嗒 Tick。
Lw_SemaphoreC_TryWait 和 Lw_SemaphoreC_Wait 的区别在于,如果计数型信号量当前的值为0,Lw_SemaphoreC_TryWait会立即退出,并返回ERROR_THREAD_WAIT_TIMEOUT,而 Lw_SemaphoreC_Wait 则会阻塞直到被唤醒。
中断服务程序可以使用 Lw_SemaphoreC_TryWait 函数尝试等待计数型信号量,Lw_SemaphoreC_TryWait 函数在计数型信号量的值为 0 时会立即返回,不会阻塞当前线程。
4.Post
释放一个计数型信号量可以调用 Lw_SemaphoreC_Post 函数。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Post(LW_HANDLE ulId);
函数 Lw_SemaphoreC_Post 原型分析:
- 此函数成功返回 0,失败返回错误号;
- 参数 ulId 是计数型信号量的句柄。
一次释放多个计数型信号量可以调用 Lw_SemaphoreC_Release 函数。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Release(LW_HANDLE ulId,
ULONG ulReleaseCounter,
ULONG *pulPreviousCounter);
函数 Lw_SemaphoreC_Release 原型分析:
- 此函数成功返回 0,失败返回错误号;
- 参数 ulId 是计数型信号量的句柄;
- 参数 ulReleaseCounter 是释放计数型信号量的次数;
- 输出参数 pulPreviousCounter 用于接收原来的信号量计数,可以为 NULL。
Lw_SemaphoreC_Release 是一个高级 API,POSIX 读写锁调用该函数来同时释放多个读写线程。
5.Clear
调用 Lw_SemaphoreC_Clear 函数将清除计数型信号量,这将使计数型信号量的初始值置为 0。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Clear(LW_HANDLE ulId);
函数 Lw_SemaphoreC_Clear 原型分析:
- 此函数成功时返回 ERROR_NONE,失败时返回错误号;
- 参数 ulId 是计数型信号量的句柄;
调用 Lw_ SemaphoreC_Flush 函数将释放等待在指定计数型信号量上的所有线程。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Flush(LW_HANDLE ulId, ULONG *pulThreadUnblockNum);
函数 Lw_SemaphoreC_Flush 原型分析:
- 此函数成功时返回 ERROR_NONE,失败时返回错误号;
- 参数 ulId 是计数型信号量的句柄;
- 输出参数 pulThreadUnblockNum 用于接收被解除阻塞的线程数,可以为 NULL。
6.Status
以下两个函数可以获得指定计数型信号量的状态信息。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_Status(LW_HANDLE ulId,
ULONG *pulCounter,
ULONG *pulOption,
ULONG *pulThreadBlockNum);
ULONG Lw_SemaphoreC_StatusEx(LW_HANDLE ulId,
ULONG *pulCounter,
ULONG *pulOption,
ULONG *pulThreadBlockNum,
ULONG *pulMaxCounter);
以上两个函数原型分析:
- 以上两个函数均返回错误号;
- 参数 ulId 是计数型信号量的句柄;
- 输出参数 pulCounter 用于接收计数型信号量当前的值;
- 输出参数 pulOption 用于接收计数型信号量的创建选项;
- 输出参数 pulThreadBlockNum 用于接收当前阻塞在该计数型信号量的线程数。
- 输出参数 pulMaxCounter 用于接收该计数型信号量的最大计数值。
7.GetName
Lw_SemaphoreC_GetName 函数可以获得指定计数型信号量的名字。
#include <SylixOS.h>
ULONG Lw_SemaphoreC_GetName(LW_HANDLE ulId, PCHAR pcName);
函数 Lw_SemaphoreC_GetName 原型分析:
- 此函数返回错误号;
- 参数 ulId 是计数型信号量的句柄;
- 输出参数 pcName 是计数型信号量的名字,pcName 应该指向一个大小为LW_CFG_OBJECT_NAME_SIZE 的字符数组。