SylixOS里的信号量

信号量

信号量(Semaphore) 又称为信号灯、旗语等,本质是一个无符号整形变量象,用于多线程之间同步或资源保护。

对信号量最核心的是两个操作pend(等待)和post(释放)。对一个信号量pend时,如果信号量大于0则获取信号量成功,信号量减一,正常退出后程序继续运行;如果为0,则要将当前线程挂起,直到其他线程释放信号量使得当前线程可以获取时才能被唤醒继续执行。对一个信号量post时,则会使得信号量加一,如果有阻塞线程因此可获得信号量,则可能会执行线程调度。

信号量有些像裸机程序里常用的标志(flag),标志就是个全局整形变量,也可以用于同步和资源保护。比如串口写完发送FIFO后,可以等一个发送完成标志,发送中断中检查到发送完成后就可以置位这个发送完成标志,此时发送函数中检查到发送完成标志就可以正常退出了。对于共同访问的资源,初始化为1,获取时置0用完再值1,这样若资源正在使用时,其他任务看到标志位0就要放弃。

信号量要比标志好用的多,首先它能保证原子操作避免同时获取或释放时出错,其次当获取失败时,可以让出CPU,进入阻塞状态,阻塞状态下的线程也可以因获取信号量而被唤醒,然后继续执行,保证整个调用过程同步实现。操作系统会包含一个等待信号量线程队列(用于存放等待信号量的线程),当信号量可以被获得时,操作系统依据某种策略从队列中选择一个可以获得信号量的线程以继续运行。

SylixOS里的信号量

SylixOS提供原生的信号量机制,其特点如下:

  • 提供四种类型:二进制信号量、计数型信号量、互斥信号量和读写信号量。
  • 支持两种等待唤醒类型:优先级等待和FIFO等待。
  • 可以设置超时时间,时间单位是心跳周期,也可以是不等待或无限等待。
  • 互斥信号量支持两种防止优先级翻转策略:优先级继承和优先级天花板。
  • 可以设置为全局对象或局部对象,其中当进程退出时不会释放全局对象资源。
  • 可以传递一个消息指针,起到传统RTOS中邮箱的作用,所以SylixOS没有提供邮箱的API。

SylixOS同时还提供POSIX标准的信号量,方便程序开发和移植,包括:

  • 匿名信号量 sem_t
  • 命名信号量 sem_t
  • 互斥信号量 pthread_mutex_t

SylixOS里信号量的通用接口

SylixOS提供的4种原生的信号量都有各自接口,但有些接口很相似,所以还提供了一些通用信号量接口。再有就是4种原生的信号量会用到一些通用的属性配置,这些配置是个位域,通过宏来定义。

通用宏配置属性

/*********************************************************************************************************
  等待时间 (超时选项)
*********************************************************************************************************/
#define LW_OPTION_NOT_WAIT                          0x00000000      /*  不等待立即退出              */
#define LW_OPTION_WAIT_INFINITE                     __ARCH_ULONG_MAX/*  永远等待                    */                                                
#define LW_OPTION_WAIT_A_TICK                       0x00000001      /*  等待一个时钟嘀嗒            */
#define LW_OPTION_WAIT_A_SECOND                     CLOCKS_PER_SEC/*  等待一秒                    */
/*********************************************************************************************************
  等待排序算法 (创建选项)
*********************************************************************************************************/
#define LW_OPTION_WAIT_PRIORITY                         0x00010000      /*  按优先级顺序等待            */
#define LW_OPTION_WAIT_FIFO                             0x00000000      /*  按先进先出顺序等待          */
/*********************************************************************************************************
  删除安全 (创建选项)
*********************************************************************************************************/
#define LW_OPTION_DELETE_SAFE                           0x00020000      /*  Mutex or RW 安全删除使能    */
#define LW_OPTION_DELETE_UNSAFE                         0x00000000      /*  Mutex or RW 非安全保护使能  */
/*********************************************************************************************************
  等待过程中遇到信号处理方式 (创建选项) (同样适用于 EVENTSET)
*********************************************************************************************************/
#define LW_OPTION_SIGNAL_INTER                          0x00040000      /*  可被信号打断 (EINTR)        */
#define LW_OPTION_SIGNAL_UNINTER                        0x00000000      /*  不可被信号打断              */
/*********************************************************************************************************
  互斥信号量优先级算 (创建选项)
*********************************************************************************************************/
#define LW_OPTION_INHERIT_PRIORITY                      0x00080000      /*  优先级继承算法              */
#define LW_OPTION_PRIORITY_CEILING                      0x00000000      /*  优先级天花板算法            */
/*********************************************************************************************************
  互斥信号量, 读写锁是否允许重入 (创建选项)
*********************************************************************************************************/
#define LW_OPTION_NORMAL                                0x00100000      /*  递归时不检查 (不推荐)       */
#define LW_OPTION_ERRORCHECK                            0x00200000      /*  Mutex or RW 递归时报错      */
#define LW_OPTION_RECURSIVE                             0x00000000      /*  Mutex or RW 支持写递归调用  */
/*********************************************************************************************************
  读写锁读写优先控制 (创建选项)
*********************************************************************************************************/
#define LW_OPTION_RW_PREFER_READER                      0x00000000      /*  读访问优先                  */
#define LW_OPTION_RW_PREFER_WRITER                      0x00400000      /*  写访问优先                  */

注意:
LW_OPTION_WAIT_PRIORITY和LW_OPTION_WAIT_FIFO只能二选一。LW_OPTION_OBJECT_GLOBAL和LW_OPTION_OBJECT_LOCAL只能二选一。

通用信号量API接口

/*********************************************************************************************************
** 函数名称: API_SemaphorePend
** 功能描述: 等待信号量
** 输 入  : 
**           ulId            事件句柄
**           ulTimeout       等待时间
** 输 出  : 
*********************************************************************************************************/
LW_API  
ULONG  API_SemaphorePend (LW_OBJECT_HANDLE  ulId, ULONG  ulTimeout)
/*********************************************************************************************************
** 函数名称: API_SemaphorePost
** 功能描述: 释放信号量
** 输 入  : 
**           ulId                   事件句柄
** 输 出  : 
*********************************************************************************************************/
LW_API  
ULONG  API_SemaphorePost (LW_OBJECT_HANDLE  ulId)
/*********************************************************************************************************
** 函数名称: API_SemaphoreFlush
** 功能描述: 释放等待信号量的所有线程
** 输 入  : 
**           ulId                   事件句柄
**           pulThreadUnblockNum    被解锁的线程数量   可以为NULL
** 输 出  : 
*********************************************************************************************************/
LW_API  
ULONG  API_SemaphoreFlush (LW_OBJECT_HANDLE  ulId, ULONG  *pulThreadUnblockNum)
/*********************************************************************************************************
** 函数名称: API_SemaphoreDelete
** 功能描述: 删除信号量
** 输 入  : 
**           pulId    事件句柄
** 输 出  : 
*********************************************************************************************************/
LW_API 
ULONG  API_SemaphoreDelete (LW_OBJECT_HANDLE  *pulId)
/*********************************************************************************************************
** 函数名称: API_SemaphorePostBPend
** 功能描述: 释放一个信号量后立即开始等待另外一个信号量(中间无任务切换发生)
** 输 入  : ulIdPost             需要释放的信号量
**           ulId                 需要等待的信号量 (二值信号量)
**           ulTimeout            等待超时时间            
** 输 出  : 
*********************************************************************************************************/
LW_API  
ULONG  API_SemaphorePostBPend (LW_OBJECT_HANDLE  ulIdPost, 
                               LW_OBJECT_HANDLE  ulId,
                               ULONG             ulTimeout)
/*********************************************************************************************************
** 函数名称: API_SemaphorePostCPend
** 功能描述: 释放一个信号量后立即开始等待另外一个信号量(中间无任务切换发生)
** 输 入  : ulIdPost             需要释放的信号量
**           ulId                 需要等待的信号量 (计数信号量)
**           ulTimeout            等待超时时间            
** 输 出  : 
*********************************************************************************************************/
LW_API  
ULONG  API_SemaphorePostCPend (LW_OBJECT_HANDLE  ulIdPost, 
                               LW_OBJECT_HANDLE  ulId,
                               ULONG             ulTimeout)

另外,系统通过宏定义还为这些接口定义了一些别名,如下:

#define Lw_Semaphore_Wait                       API_SemaphorePend
#define Lw_Semaphore_Get                        API_SemaphorePend
#define Lw_Semaphore_Take                       API_SemaphorePend

#define Lw_Semaphore_Post                       API_SemaphorePost
#define Lw_Semaphore_Give                       API_SemaphorePost
#define Lw_Semaphore_Send                       API_SemaphorePost

#define Lw_Semaphore_Flush                      API_SemaphoreFlush
#define Lw_Semaphore_Delete                     API_SemaphoreDelete

#define Lw_Semaphore_PostBPend                  API_SemaphorePostBPend
#define Lw_Semaphore_PostCPend                  API_SemaphorePostCPend
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ScilogyHunter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值