互斥信号量

目录

1、Creat

2、Delete

3、Wait

4、Post

5、Statu


互斥信号量

在介绍二进制信号量时,曾讨论到如果二进制信号量创建时设置参数 bInitValue 为TRUE,则可以用于互斥访问共享资源。实际上,SylixOS 的二进制信号量实现的互斥性是将一个变量初始化标记为 1,等待信号量(Wait)时将该变量减 1(此时等于 0),如果另一个线程再次等待该信号量将阻塞,直到该信号量被释放(变量加 1),这样就实现了共享资源的互斥访问。

如果系统中只有两个线程,上面的过程是没有问题的。但是一旦有多个线程介入,上面过程将出现以下问题:

一个高优先级的线程可能也要访问同一个共享资源(这是完全有可能的),此时只能阻塞等待,但是可能会有另一个中等优先级的线程将占有信号量的线程抢占。这个过程导致了高优先级线程很长时间得不到运行(这是 SylixOS 不允许出现的情况)。

以上过程出现的问题就是经典的优先级反转问题。

互斥信号量用于共享资源需要互斥访问的场合,可以理解为初始值为 TRUE 的带优先级天花板和优先级继承机制(意在解决优先级反转问题)的二进制信号量,只有拥有互斥信号量的线程才有权释放互斥信号量。

 

1、Creat

一个 SylixOS 互斥信号量必须要调用 Lw_SemaphoreM_Create 函数创建之后才能使用,如果创建成功,该函数将返回一个互斥信号量的句柄。

#include <SylixOS.h>
LW_HANDLE Lw_SemaphoreM_Create(CPCHAR pcName,
     UINT8 ucCeilingPriority,
     ULONG ulOption,
     LW_OBJECT_ID *pulId);

函数 Lw_SemaphoreM_Create 原型分析:

  • 此函数成功返回互斥信号量的句柄,失败返回 NULL 并设置错误号;
  • 参数 pcName 是互斥信号量的名字;
  • 参数 ucCeilingPriority 在使用优先级天花板算法时有效,此参数为天花板优先级;
  • 参数 ulOption 是互斥信号量的创建选项;
  • 输出参数 pulId 返回互斥信号量的句柄(同返回值),可以为 NULL

创建选项包含了二进制信号的创建选项,此外还可以使用,如下表所示的互斥信号量特有的创建选项。

需要注意,LW_OPTION_INHERIT_PRIORITY 和 LW_OPTION_PRIORITY_CEILING只能二选一,同样 LW_OPTION_NORMAL LW_OPTION_ERRORCHECK 及LW_OPTION_RECURSIVE 只能三选一。

 

2、Delete

一个不再使用的互斥信号量,可以调用以下函数将其删除。删除后的信号量系统自动回收其占用的系统资源(试图使用被删除的互斥信号量将出现未知的错误)

#include <SylixOS.h>
ULONG Lw_SemaphoreM_Delete(LW_HANDLE *pulId);
函数 Lw_SemaphoreM_Delete 原型分析:
  • 此函数返回错误号;
  • 参数 pulId 是互斥信号量的句柄。
     

3、Wait

线程如果需要等待一个互斥信号量,可以调用 Lw_SemaphoreM_Wait 函数。

#include <SylixOS.h>
ULONG Lw_SemaphoreM_Wait(LW_HANDLE ulId, ULONG ulTimeout);

函数 Lw_SemaphoreM_Wait 原型分析:

  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是互斥信号量的句柄;
  • 参数 ulTimeout 是等待的超时时间,单位为时钟嘀嗒 Tick

4、Post

释放一个互斥信号量使用 Lw_SemaphoreM_Post 函数。
 
 
#include <SylixOS.h>
ULONG Lw_SemaphoreM_Post(LW_HANDLE ulId);

函数 Lw_SemaphoreM_Post 原型分析:

  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是互斥信号量的句柄。

需要注意的是,只有互斥信号量的拥有者才能释放该互斥信号量。

5、Statu

下面函数可以获得互斥信号量的状态信息。
 
#include <SylixOS.h>
ULONG Lw_SemaphoreM_Status(LW_HANDLE ulId,
     BOOL *pbValue,
     ULONG *pulOption,
     ULONG *pulThreadBlockNum);
ULONG Lw_SemaphoreM_StatusEx(LW_HANDLE ulId,
     BOOL *pbValue,
     ULONG *pulOption,
     ULONG *pulThreadBlockNum,
     LW_HANDLE *pulOwnerId);
以上两个函数原型分析:
  • 函数成功返回 0,失败返回错误号;
  • 参数 ulId 是互斥信号量的句柄;
  • 输出参数 pbValue 用于接收互斥信号量当前的状态;
  • 输出参数 pulOption 用于接收互斥信号量的创建选项;
  • 输出参数 pulThreadBlockNum 用于接收当前阻塞在该互斥信号量的线程数。
  • 输出参数 pulOwnerId 用于接收当前拥有该互斥信号量的线程的句柄。
 
获得一个互斥信号量的名字,可以调用以下函数:
#include <SylixOS.h>
ULONG Lw_SemaphoreM_GetName(LW_HANDLE ulId, PCHAR pcName);
函数 Lw_SemaphoreM_GetName 原型分析:
  • 此函数成功返回 0,失败返回错误号;
  • 参数 ulId 是互斥信号量的句柄;
  • 输出参数 pcName 是互斥信号量的名字,pcName 应该指向一个大小为LW_CFG_OBJECT_NAME_SIZE 的字符数组。
 
 
 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值