vxworks系统学习----二进制信号量

简介: vxworks系统学习----二进制信号量

1 信号量概念


在vxworks中使用信号量工具对互斥与任务同步进行操作。在wind内核中存在二进制信号量、互斥信号量及计

数信号量。互斥:当共享地址空间进行简单的数据交换时,为避免竞争需要对内存进行互锁,即多个任务访问共享内存时,体现出来的排它性。使用二进制信号量就可以很方便地实现互斥,当多个任务访问共享资源时,对该资源设置一个信号量(相当于令牌),那么拿到该令牌的任务就可以独享该资源。


2 二进制信号量互斥实现说明与代码模型参考


二进制信号量需要的系统开销最小,因而特别适合于高性能的需求。

注意:

(1)互斥中的信号量与任务优先级的关系:任务的调度还是按照任务优先级进行,但是在使用内存的时候只有一个任务获得信号量,也就是说还是按照任务优先级获得信号量从而访问资源。只有当前使用资源的任务使用semGive()释放信号量后,其它任务按照优先级才可以获得信号量。

(2)信号量属性中的参数为:SEM_Q_PRIORITY。而且在创建信号量的时候必须把信号量置为满SEM_FULL,即信号量可用,等待信号的任务可以根据优先级顺序(SEM_Q_PRIORITY)或者先进先出(SEM_Q_FIFO)进行排队。

如图1所示,使用semBCreate(),分配并初始化一个二进制信号量,返回值为一信号量ID,为其他信号量控制函数的应用提供句柄,并设置资源可用(full)还是不可(empty)。


任务可以调用semTake()函数提取二进制信号量,如果信号量可用(full)那么将变得不可用(empty),同时任务继续执行。如果信号量不可用(empty),调用semTake()函数的任务将被放到一个阻塞队列中,处于等待信号量可用的状态(pending挂起)。

semGive()可用于释放信号量。若信号量不可用(empty)并且没有任务在等待它,那么该信号量将变得可用(full),若信号量不可用(empty)并且有任务在等待它,那么 阻塞队列中的第一个任务将得到该信号量变得不阻塞, 同时 该信号量仍旧不可用(empty),若信号量可用(full),调用semGive()不产生任何影响。

 

微信图片_20230116140915.png

互斥模型程序说明:


<span style="color:#FFCCCC;"><span style="color:#330033;">SEM_ID semMutex;

semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL);//优先级顺序排队,信号量可用

task(void)
{
      
      semTake(semMutex, WAIT_FOREVER);//得到信号量,即相当于得到使用资源的令牌
       
       //临界区,某一个时刻只能由一个任务访问
       
       semGive(semMutex);

}</span></span>

3 二进制信号量任务同步实现

任务同步:任务利用信号量控制自己的运行进度,按照一定的先后顺序执行。例如为了任务A与B同步,A与B可以共享一个信号量,初始值设置为不可用,在A之后调用semGive在B之前调用semTakeSEM_ID 即可。

SEM_ID  semSync;
semSync = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
taskA(void)
{ semGive(semSync); //信号量释
}taskB(void){ semTake(semSync, WAIT_FOREVER); //获取信号量}

注意:


(1)创建的新的信号量初始值应当为不可用(empty),因而可能使得优先级翻转,即高优先级任务在低优先级任务之后执行;

(2)属性参数设置:SEM_Q_FIFO,SEM_EMPTY。在不同的TASK中分别单独调用semTake(),semGive()且先后顺序不能颠倒。

(3)禁止删除那些任务正在请求信号量。

(4)semTake()不可以在中断中调用,因为调用semTake()的函数可能被挂起,而中断不可以被挂起。semGive()可以在中断中调用


例子程序:

SEM_ID semFs;
SEM_ID semFss;
SEM_ID semFex;
semFs = semBCreate(SEM_Q_FIFO,  SEM_EMPTY);
semFss = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
semFex = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
void t_imaGet(void)
{
    printf("task t_imaGet get the semaphore\n ");
    semGive(semFs);   //释放信号量
}

void t_imaJud(void)
{
    semTake(semFs, WAIT_FOREVER);//确保优先级不反转
    printf("task  imaJud get the semaphore\n");
    semGive(semFss);
}
void t_imaPro(void)

{
    semTake(semFss, WAIT_FOREVER);
    printf("task imaProget the semaphore\n");
    semGive(semFex);
}
void t_imaExc(void)
{

    semTake(semFex, WAIT_FOREVER);
    printf("task imaExcthe semaphore\n");
}

void start(void)
{
    int tGetId, tJudId, tProId, tExcId;
    tGetId = taskSpawn("tPget", 200, 0, 1000,(FUNCPTR)t_imaGet, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    tJudId = taskSpawn("tPjud",201,0,1000,(FUNCPTR)t_imaJud,3,0,0,0,0,0,0,0,0,0); 
    tProId = taskSpawn("tPpro",202,0,1000,(FUNCPTR)t_imaPro,3,0,0,0,0,0,0,0,0,0); 
    tExcId = taskSpawn("tPexc",203,0,1000,(FUNCPTR)t_imaExc,3,0,0,0,0,0,0,0,0,0);
}
目录
相关文章
|
Kubernetes API 调度
容器编排工具有哪些
容器编排工具有哪些
|
Linux 开发工具 内存技术
国产之路:复旦微zynq调试笔记2--PL网口
PL侧的网口需求相较于PS部分还是有一定区别的,主要需要添加axi ethernet 的移植
3929 0
|
云计算 项目管理 云安全
附PPT下载 | 小邪:新基建之云上IT研发路 - 基于云架构的研发模式演进
企业的数字化上云已经成为社会共识。5G、工业互联网、人工智能、云计算作为数字经济的主要基础设施,将成为中国新基建的主要内容。云将给IT部门及IT人员带来研发运维方面的革命性的变化与冲击。本次分享将由阿里巴巴集团副总裁、云智能基础产品事业部负责人蒋江伟为大家介绍阿里巴巴面向互联网、面向云的研发模式的演
1887 0
|
存储 算法 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (一)
`memcpy()` 和 `memmove()` 是C语言中的两个内存操作函数。 `memcpy()` 函数用于从源内存区域复制指定数量的字节到目标内存区域。它不处理内存重叠的情况,如果源和目标区域有重叠,结果是未定义的。函数原型如下: ```c void *memcpy(void *dest, const void *src, size_t num); ```
1414 6
|
Linux iOS开发 开发者
Qt问题(二):无法定位程序输入点于动态链接库
动态链接库(Dynamic Link Library,简称DLL)是一种可执行文件格式,常见于Windows操作系统中,而在Linux和macOS等其他操作系统中,相似的概念通常被称为共享库(Shared Library)。动态链接库允许程序在运行时加载所需的代码和数据,而不是在编译时静态链接到应用程序中。这种方式带来了几个重要的优点:
2520 3
|
小程序
手写签名-微信小程序
手写签名-微信小程序
321 1
|
安全 数据挖掘 数据处理
python数据分析——数据分析如何合法的进行
数据分析如何合法的进行,这是一个在当今数字化时代愈发重要的问题。随着大数据技术的快速发展,数据分析已经渗透到各个领域,从商业决策到政策制定,从医疗健康到个人生活,无处不在。然而,数据的获取、存储、处理和使用都必须遵循法律法规,尊重个人隐私,保护数据安全。
338 1
|
存储 分布式计算 JavaScript
Fury系列(四):一个比Kryo/Hessian快30~40倍的类型前后兼容序列化器
问题背景类型前后兼容是复杂业务场景序列化的常见需求。在快速迭代的业务场景当中,读写端经常发生对象字段发生变更:在线应用场景:线上SOFA/HSF应用提供服务给多个调用方,服务的滚动升级以及各个调用方独立更新都可能导致对象类型不一致的情况;在线服务场景:在线服务框架常驻不更改对象类型,但调用方业务逻辑变动独立更新导致对象字段跟服务端不一致;对象持久化场景:对象数据序列化后持久化写入存储(如Spark
2155 2
Fury系列(四):一个比Kryo/Hessian快30~40倍的类型前后兼容序列化器
|
存储 网络协议 安全
UDP通信机制详解
UDP通信机制详解
1447 0
|
存储 缓存 小程序
【小程序开发必备】微信小程序常用API全介绍,附示例代码和使用场景
本篇博文介绍了微信小程序常用API,包括网络请求、数据缓存、交互反馈、设备、媒体、界面、开放接口等方面。每个API都附有详细的介绍和示例代码,以及使用场景。这些API可以帮助小程序开发者快速实现各种功能和交互效果,是小程序开发的必备工具。无论是初学者还是有一定经验的开发者,都能从本篇博文中学到很多实用的技巧和知识。
1762 0