二进制信号量

目录

1.creat

2.delete

3.wait

4.post

5.clear

6.属性


二进制信号量

SylixOS 的二进制信号量实现的互斥性是将一个变量初始化标记为 1,等待信号量(Wait)时将该变量减 1(此时等于 0),如果另一个线程再次等待该信号量将阻塞,直到该信号量被释放(变量加 1),这样就实现了共享资源的互斥访问。

二进制信号量的基本操作函数在线程与线程之间中断与线程之间的操作过程如下图所示。

 SylixOS 二进制信号量
扫描二维码关注公众号,回复: 12910173 查看本文章

1.creat

二进制信号量主要应用在以下场合:

  • 有允许线程访问的一个资源,使用二进制信号量作为互斥手段,初始值为 TRUE
  • 线程或中断通知另一个线程某件事件发生,初始值为 FALSE
SylixOS 提供函数 Lw_SemaphoreB_Create 创建一个二进制信号量
#include <SylixOS.h>
LW_HANDLE Lw_SemaphoreB_Create(CPCHAR pcName, 
    BOOL bInitValue, 
    ULONG ulOption, 
    LW_OBJECT_ID *pulId);
函数 Lw_SemaphoreB_Create 原型分析:
  • 此函数返回二进制信号量的句柄,失败时为 NULL 并设置错误号;
  • 参数 pcName 是二进制信号量的名字;
  • 参数 bInitValue 是二进制信号量的初始值FALSE TRUE);
  • 参数 ulOption 是二进制信号量的创建选项如图 3 所示;
  • 输出参数 pulId 用于返回二进制信号量的句柄(同返回值),可以为 NULL

参数 bInitValue 的不同决定了二进制信号量的用途不同,当 bInitValue 的值为 TRUE 时可以用于共享资源的互斥访问,如图1 所示。当 bInitValue 的值为 FALSE 时可以用于多线程间的同步,如图 2  所示。

图 1 共享资源的互斥访问
图 2 线程同步

信号量的创建选项参数见图 3 所示。SylixOS 提供了两种信号量等待队列:优先级(LW_OPTION_WAIT_PRIORITY)和 FIFO(LW_OPTION_WAIT_FIFO)。优先级方式则根据线程的优先级从队列中取出符合条件的线 程运行;FIFO 方式则根据先入先出的原则从队列中取出符合条件的线程运行。

需要注意的是,LW_OPTION_WAIT_PRIORITY LW_OPTION_WAIT_FIFO 只能二选一,同样LW_OPTION_OBJECT_GLOBAL LW_OPTION_OBJECT_LOCAL也只能二选一。其中LW_OPTION_OBJECT_GLOBAL 代表一种全局对象,LW_OPTION_OBJECT_LOCAL 代表一种局部对象,当进程退出时不会释放全局对象资源(除非特殊,一般不使用 GLOBAL 对象)。

图 3  二进制信号量的创建选项

2.delete

不再需要的二进制信号量可以调用Lw_SemaphoreB_Delete函数将其删除SylixOS 将回收其占用的内核资源(试图使用被删除的二进制信号量将出现未知的错误)。

#include <SylixOS.h>
ULONG Lw_SemaphoreB_Delete(LW_HANDLE *pulId)
函数 Lw_SemaphoreB_Delete 原型分析:
  • 此函数成功返回 0,失败返回错误号;
  • 参数 pulId 是二进制信号量的句柄。 

3.wait

一个线程如果需要 等待一个二进制信号量 ,可以调用 Lw_SemaphoreB_Wait 函数。
#include <SylixOS.h>
ULONG Lw_SemaphoreB_Wait(LW_HANDLE ulId, ULONG ulTimeout);
ULONG Lw_SemaphoreB_TryWait(LW_HANDLE ulId);
以上函数原型分析:
  • 函数成功返回 0,失败返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
  • 参数 ulTimeout 是等待的超时时间,单位为时钟节拍 Tick

参数 ulTimeout除了可以使用数字外还可以使用如图 4 所示的宏。SylixOS 为二进制信号量等待提供了一种超时机制,当等待的时间超时时立即返回并设置 errno 为 ERROR_THREAD_WAIT_TIMEOUT。
 

图 4 参数 ulTimeout 可用宏
 

中断服务程序不能调用 Lw_SemaphoreB_Wait 函数来等待一个二进制信号量,因为该函数在二进制信号量值为 FALSE 时会阻塞当前执行的任务,而中断服务程序用来处理最紧急的事情,因此是不允许被阻塞的,否则其他线程将得不到调度的机会。

 

中断服务程序可以使用 Lw_SemaphoreB_TryWait 函数尝试等待二进制信号量,因为Lw_SemaphoreB_TryWait 函数在二进制信号量的值为 FALSE 时会立即返回,不会阻塞当前线程。

4.post

释放一个二进制信号量可以调用 Lw_SemaphoreB_PostLw_SemaphoreB_Post2 或者Lw_SemaphoreB_Release 函数。 Lw_SemaphoreB_Post2 函数返回时可以通过参数 pulId 返回被激活的线程句柄,如果参数 pulId 被置为 NULL 时行为与Lw_SemaphoreB_Post 相同。

#include <SylixOS.h>
ULONG Lw_SemaphoreB_Post(LW_HANDLE ulId);
函数 Lw_SemaphoreB_Post 原型分析:
  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是二进制信号量的句柄。
#include <SylixOS.h>
ULONG Lw_SemaphoreB_Post2(LW_HANDLE ulId, LW_HANDLE *pulId);
函数 Lw_SemaphoreB_Post 原型分析:
  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
  • 参数 pulId 返回被激活的线程 ID
#include <SylixOS.h>
ULONG Lw_SemaphoreB_Release(LW_HANDLE ulId, ULONG ulReleaseCounter, BOOL *pbPreviousValue);
函数 Lw_SemaphoreB_Release 原型分析:
  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
  • 参数 ulReleaseCounter 是释放二进制信号量的次数;
  • 输出参数 pbPreviousValue 用于接收原来的二进制信号量状态,可以为 NULL

5.clear

调用 Lw_ SemaphoreB_Clear 函数将清除二进制信号量,这将使二进制信号量的初始值置为 FALSE

#include <SylixOS.h>
ULONG Lw_SemaphoreB_Clear(LW_HANDLE ulId);
函数 Lw_SemaphoreB_Clear 原型分析:
  • 此函数返回错误号;
  • 参数 ulId 是二进制信号量的句柄。

调用 Lw_ SemaphoreB_Flush 函数将释放在指定信号量等待的所有线程

#include <SylixOS.h>
ULONG Lw_SemaphoreB_Flush(LW_HANDLE ulId, ULONG *pulThreadUnblockNum);
函数 Lw_SemaphoreB_Flush 原型分析:
  • 此函数返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
  • 输出参数 pulThreadUnblockNum 用于接收被解除阻塞的线程数,可以为 NULL

6.属性

Lw_SemaphoreB_Status 函数返回一个有效 信号量的状态信息
 
#include <SylixOS.h>
ULONG Lw_SemaphoreB_Status(LW_HANDLE ulId, BOOL *pbValue, ULONG *pulOption, ULONG *pulThreadBlockNum);
函数 Lw_SemaphoreB_Status 原型分析:
  • 此函数返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
    • 输出参数 pbValue 用于接收二进制信号量当前的值(FALSE TRUE);
  • 输出参数 pulOption 用于接收二进制信号量的创建选项;
  • 输出参数 pulThreadBlockNum 用于接收当前阻塞在该二进制信号量的线程数。
调用 Lw_SemaphoreB_GetName 函数可以获得指定 信号量的名字
 
#include <SylixOS.h>
ULONG Lw_SemaphoreB_GetName(LW_HANDLE ulId, PCHAR pcName)
函数 Lw_SemaphoreB_GetName 原型分析:
  • 此函数返回错误号;
  • 参数 ulId 是二进制信号量的句柄;
  • 输出参数 pcName 是二进制信号量的名字,pcName 应该指向一个大小为LW_CFG_OBJECT_NAME_SIZE 的字符数组。
 

猜你喜欢

转载自blog.csdn.net/Liangren_/article/details/108482986