threadx学习笔记(6)信号量_threadx 信号量-程序员宅基地

技术标签: 学习  笔记  

文章参考:

ThreadX学习(6)——信号量_threadx 信号量-程序员宅基地

 semaphore意为信号量

有两种操作会影响计数信号量的值:tx_semaphore_get和tx_semaphore_put。get操作将信号量减少1。如果信号量为0,则get操作失败。与get操作相反的是put操作,它将信号量增加1。

二值信号量

二值信号量是一种同步机制,用于控制对共享资源的访问。它只有两个值:0和1。当信号量的值为1时,表示资源可用;当值为0时,表示资源被占用。线程或进程在访问共享资源前,会尝试减少(P 操作)信号量的值;访问结束后,会增加(V 操作)信号量的值。如果一个线程尝试执行P操作时信号量的值为0,则该线程会阻塞,直到信号量的值变为1。

和互斥锁类似。但是二值信号量没有互斥锁的所有权概念,即只有加锁的线程才可以解锁,二值信号量所有的线程都可以进行v操作,所以二值信号量无法解决优先级反转的问题,即便如此,信号量更加通用,还可以用于事件通知和线程间同步。且信号量速度快于互斥锁。

事件通知

计数信号量还可以用于事件通知,就像在生产者-消费者应用程序中一样。

在这个应用程序中,使用者尝试在“消耗”资源(比如队列中的数据)之前获得计数信号量;每当生产者提供一些可用的东西时,它就增加信号量计数。换句话说,生产者将实例放置在信号量中,而消费者尝试从信号量中获取实例。

这类信号量的初始值通常为0,直到生产者为消费者准备好一些东西时才会增加。

1.tx_semaphore_create
TX_SEMAPHORE semaphore_ptr; //先定义再创建
UINT  tx_semaphore_create(	TX_SEMAPHORE *semaphore_ptr, 
							CHAR *name_ptr, 
							ULONG initial_count)

第 1 个参数 semaphore_ptr 是信号量控制块地址。
第 2 个参数 name_ptr 是信号量名。
第 3 个参数 initial_count 是该信号量的初始计数。
返回值:
TX_SUCCESS(0x00)成功创建。
TX_SEMAPHORE_ERROR: (0x0C)无效信号量指针。要么指针是NULL,要么信号量已经创建。
TX_CALLER_ERROR:(0x13)无效的服务调用者。

和之前的线程,互斥锁,计数器等类似,创建的时候在tx_application_define中创建。根据打印结果,信号量创建成功。

VOID tx_application_define(void  *first_unused_memory)
{
	char buffer[256];
	UINT aa= tx_semaphore_create(&semaphore_ptr,"semaphore 0",1);
	snprintf(buffer,sizeof(buffer),"%u\n",aa);
	HAL_UART_Transmit(&huart1,(uint8_t *)buffer,strlen(buffer),HAL_MAX_DELAY);
	
  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,  
            thread_0_stack, DEMO_STACK_SIZE, 
            1, 1, 10, TX_AUTO_START);
	tx_thread_create(&thread_1, "Thread 1", thread_1_entry, 0,
                     thread_1_stack, DEMO_STACK_SIZE,
                     2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
}

2.tx_semaphore_delete
UINT  tx_semaphore_delete(TX_SEMAPHORE *semaphore_ptr)

删除信号量

  • 第 1 个参数 semaphore_ptr 是信号量控制块地址。

返回值:

  • TX_SUCCESS(0x00)成功删除。
  • TX_SEMAPHORE_ERROR: (0x0C)无效计数信号量指针。
  • TX_CALLER_ERROR:(0x13)无效的服务调用者。

在线程1中调用信号量删除函数,根据打印结果,成功删除信号量。

void thread_1_entry(ULONG thread_input)
{	
	char buffer[256];
	UINT aa= tx_semaphore_delete(&semaphore_ptr);
	snprintf(buffer,sizeof(buffer),"%u\n",aa);
	HAL_UART_Transmit(&huart1,(uint8_t *)buffer,strlen(buffer),HAL_MAX_DELAY);

	char cc[]="线程2\n";
	HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
}

 3.tx_semaphore_get
UINT  tx_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, 
							CHAR **name, 
							ULONG *current_value, 
							TX_THREAD **first_suspended, 
							ULONG *suspended_count, 
							TX_SEMAPHORE **next_semaphore)

获取信号量

每次获取信号量,计数减少1。

第 1 个参数 semaphore_ptr 是信号量控制块地址。
第 2 个参数 wait_option 是等待选项:
TX_NO_WAIT:不等待,直接返回结果。
TX_WAIT_FOREVER:一直等待直到获取信号量。
timeout value:设置等待时间(时钟脉冲)。
返回值:
TX_SUCCESS(0x00)成功获取。
TX_DELETED: (0x01)线程挂起时计数信号量被删除。
TX_NO_INSTANCE: (0x0D)服务无法检索计数信号量的实例(在指定的等待时间内信号量计数为零)。
TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、计时器或ISR中止。
TX_SEMAPHORE_ERROR: (0x0C)无效计数信号量指针。
TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。

示例代码先让线程获取信号量,再打印信号量信息,再是释放信号量,再次打印信号量信息,经过比对可以得到,获取信号量确实会让计数减少1。在释放信号量后,计数加1。

void thread_1_entry(ULONG thread_input)
{
	CHAR 					*name;
	ULONG 				current_value;
	TX_THREAD 		*first_suspended;
	ULONG 				suspended_count;
	TX_SEMAPHORE 	*next_semaphore;
	
	UINT aa=tx_semaphore_get(&semaphore_ptr,TX_NO_WAIT);
	//先获取信号量
	huartsend(aa);
	UINT bb=tx_semaphore_info_get(&semaphore_ptr, 
							&name, 
							&current_value, 
							&first_suspended, 
							&suspended_count, 
							&next_semaphore);
	//再打印此时信号量的信息
	huartsend(bb);
	char buffer[256];
	snprintf(buffer,sizeof(buffer),"name:%s\nvalue:%lu\nsuspendcount:%lu\n", 
							name, 
							current_value, 
							suspended_count);
	HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
	UINT dd=tx_semaphore_put(&semaphore_ptr);
	//再释放信号量
	huartsend(dd);
	UINT ee=tx_semaphore_info_get(&semaphore_ptr, 
							&name, 
							&current_value, 
							&first_suspended, 
							&suspended_count, 
							&next_semaphore);
	//再打印此时信号量的信息
	huartsend(ee);
	snprintf(buffer,sizeof(buffer),"name:%s\nvalue:%lu\nsuspendcount:%lu\n", 
							name, 
							current_value, 
							suspended_count);
	HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);

	char cc[]="线程2\n";
	HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
}
/* USER CODE END 4 */
void huartsend(UINT cc)
{
	char buffer[256];
	snprintf(buffer,sizeof(buffer),"%u\n",cc);
	HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}

4.tx_semaphore_info_get 
UINT  tx_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, 
							CHAR **name, 
							ULONG *current_value, 
							TX_THREAD **first_suspended, 
							ULONG *suspended_count, 
							TX_SEMAPHORE **next_semaphore)

获取信号量信息:

第 1 个参数 semaphore_ptr 是信号量控制块地址。
第 2 个参数 name 是信号量名字符串,获取后存储的指针。
第 3 个参数 current_value 是信号量当前计数,获取后存储的指针。
第 4 个参数 first_suspended 是等待该信号量(信号量挂起列表)的第一个线程TCB指针,获取后存储的指针。
第 5 个参数 suspended_count 是等待该信号量(信号量挂起列表)的线程数,获取后存储的指针。
第 6 个参数 next_semaphore 是信号量列表的下一个信号量控制块指针,获取后存储的指针。
返回值:
TX_SUCCESS(0x00)成功获取信号量信息。
TX_SEMAPHORE_ERROR: (0x0C)无效信号量指针。

相关示例代码在获取信号量函数中展示过了。

5.tx_semaphore_put 
UINT  tx_semaphore_put(TX_SEMAPHORE *semaphore_ptr)

释放信号量,计数加一:

第 1 个参数 semaphore_ptr 是信号量控制块地址。

返回值:

TX_SUCCESS(0x00)成功释放。

TX_SEMAPHORE_ERROR: (0x0C)无效信号量指针。

相关示例代码在获取信号量函数中展示过了。

6.tx_semaphore_prioritize
UINT  tx_semaphore_prioritize(TX_SEMAPHORE *semaphore_ptr)

信号量挂起列表的最高优先级线程置队头:

第 1 个参数 semaphore_ptr 是信号量控制块地址。

返回值:

TX_SUCCESS(0x00)成功或挂起列表为空。

TX_SEMAPHORE_ERROR: (0x0C)无效信号量指针。

在获取信号量线程的示例代码后面加上tx_semaphore_prioritize函数,根据打印结果显示,函数调用成功。

void thread_1_entry(ULONG thread_input)
{
	CHAR 					*name;
	ULONG 				current_value;
	TX_THREAD 		*first_suspended;
	ULONG 				suspended_count;
	TX_SEMAPHORE 	*next_semaphore;
	
	UINT aa=tx_semaphore_get(&semaphore_ptr,TX_NO_WAIT);
	//先获取信号量
	huartsend(aa);
	UINT bb=tx_semaphore_info_get(&semaphore_ptr, 
							&name, 
							&current_value, 
							&first_suspended, 
							&suspended_count, 
							&next_semaphore);
	//再打印此时信号量的信息
	huartsend(bb);
	char buffer[256];
	snprintf(buffer,sizeof(buffer),"name:%s\nvalue:%lu\nsuspendcount:%lu\n", 
							name, 
							current_value, 
							suspended_count);
	HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
	UINT dd=tx_semaphore_put(&semaphore_ptr);
	//再释放信号量
	huartsend(dd);
	UINT ee=tx_semaphore_info_get(&semaphore_ptr, 
							&name, 
							&current_value, 
							&first_suspended, 
							&suspended_count, 
							&next_semaphore);
	//再打印此时信号量的信息
	huartsend(ee);
	snprintf(buffer,sizeof(buffer),"name:%s\nvalue:%lu\nsuspendcount:%lu\n", 
							name, 
							current_value, 
							suspended_count);
	HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
	
	UINT ff=tx_semaphore_prioritize(&semaphore_ptr);
	huartsend(ff);
	

	char cc[]="线程2\n";
	HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_71240643/article/details/136557629

智能推荐

华为鸿蒙系统2021年上市,2021年,华为开始规划自有操作系统“鸿蒙”。-程序员宅基地

文章浏览阅读626次。原标题:2021年,华为开始规划自有操作系统“鸿蒙”。2019年5月24日,国家知识产权局商标局网站显示,华为已申请“华为鸿蒙”商标,申请日期是2018年8月24日,注册公告日期是2019年5月14日,专用权限期是从2019年5月14日到2029年5月13日。 2019年5月17日,由任教授领导的华为操作系统团队开发了自主产权操作系统——鸿蒙。2019年8月9日,华为正式发布鸿蒙系统。同时余承东也..._鸿蒙系统正式上市时间是哪一年

AE - 03.符号库设计与实现_ae符号库设计与实现-程序员宅基地

文章浏览阅读438次。03.符号库设计与实现流程图#####引用类库及接口描述引用类库:ESRI.ArcGIS.Carto:包括一些数据显示的接口和类,如ILegend,IMap,ILayerESRI.ArcGIS.Geodatabase:提供操作地理数据库的接口,如IWorkspace,IDataset,IFeatureESRI.ArcGIS.DataSourcesFile:提供打开矢量数据的接口..._ae符号库设计与实现

Kafka-2.0.0安装步骤及集群_kafka2.0安装-程序员宅基地

文章浏览阅读1k次。首先确认安装JDK8及以上版本,确认已安装ZooKeeper,ZooKeeper-3.4.12安装步骤第一步:下载Kafka下载地址选择 kafka_2.11-2.0.0.tgz版本,复制到安装目录,解压缩第二步:修改配置文件# borker的编号,如果集群中有多个,则每个borker需设置不同的编号broker.id=0#broker对外提供服务入口的端口(默认9092)listeners=PLAINTEXT://:9092#存放消息日志文件地址log.dirs=/data/ho_kafka2.0安装

监听网络变化--含7.0以上适配_android.net.conn.connectivity_change-程序员宅基地

文章浏览阅读3.7k次,点赞3次,收藏7次。我们知道最早监听网络变化,是通过广播,静态或动态注册广播,处理"android.net.conn.CONNECTIVITY_CHANGE"这个action就可以了intent就可以了。我们发现"android.net.conn.CONNECTIVITY_CHANGE"这个action已经加了注解@Deprecated,不推荐使用了。根据注释说明,7.0及以上静态注册广播(manifest中)..._android.net.conn.connectivity_change

计算机学习目标_bytetrack+yolov5 c++-程序员宅基地

文章浏览阅读291次。开个坑_bytetrack+yolov5 c++

fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory-程序员宅基地

文章浏览阅读4.8k次,点赞12次,收藏39次。fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory

随便推点

第4章c语言作业_c语言第四章作业-程序员宅基地

文章浏览阅读591次。第四章 选择结构程序设计例1:输入两个实数,按由小到大的顺序输出这两个数#include<stdio.h>int main(){ float a,b,c,t;scanf("%f,%f,%f",&a,&b,&c); if(a>b) { _c语言第四章作业

PCL1.8+Ubuntu16.04安装详解-程序员宅基地

文章浏览阅读4.7w次,点赞16次,收藏76次。方式一:官网prebuild版本sudo add-apt-repository ppa:v-launchpad-jochen-sprickerhof-de/pclsudo apt-get updatesudo apt-get install libpcl-all可能是因为国内的关系,并没有更新 apt-get 成功方式二:安装 prebuilt DEB file for PCL 1.8_pcl1.8+ubuntu16.04安装详解

win11 文件拖到任务栏无法打开的解决办法_win11文件拖到任务栏打不开-程序员宅基地

文章浏览阅读6.9k次,点赞6次,收藏9次。计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System。解决win11 文件拖到任务栏无法打开的问题。实测win11家庭版、专业版均可以使用。系统更新到最新版也可以使用。win11中重新设置一个账户,不要使用Administrator账户,使用普通账户即可打开。重启后即可 正常使用。文件拖到任务栏即可打开。可能遇到的问题解决。1.依旧无法拖拽打开。2.依旧无法拖拽打开。3.注册表不会修改。_win11文件拖到任务栏打不开

STM32WB55大半年开发记录,血氧心率检测手环-程序员宅基地

文章浏览阅读6.3k次,点赞15次,收藏38次。在长达大半年的STM32WB55蓝牙手环开发的过程当中,让我感受到了这款芯片的魅力和ST为其倾力打造的生态环境是真的很不错!不过在开发STM32WB55这款芯片的时候,刚开始能找到资料确实太少了,入门真的门槛稍微高了点。我是靠着官方给的英文文档一步一步啃过来的。到现在为止大致掌握了STM32WB55的开发流程,以及在它的蓝牙方面的开发应用。我已经成功的使用STM32CUBEMAX生成多个蓝牙的profile包括三轴传感器,血氧、心率,数字麦克风等多个传感器蓝牙传输的方法。有时间再慢慢更新,记录._stm32wb55

SpringBoot整合Elastic-job实现_springboot + elasticjob-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏13次。SpringBoot整合Elastic-job实现【基本整合】:原理参考:Elastic-Job原理(1)引用pom依赖:<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <..._springboot + elasticjob

Attensleep:一种基于注意力的单通道EEG睡眠分期深度学习方法_an attention-based deep learning approach for slee-程序员宅基地

文章浏览阅读791次。AttenSleep 基于注意力的深度学习架构从单通道EEG信号中进行睡眠阶段分类从基于多分辨率卷积神经网络( MRCNN )和自适应特征重标定( AFR )的特征提取模块入手。MRCNN可以提取低频和高频特征,而AFR可以通过建模特征之间的相互依赖关系来提高提取特征的质量。第二个模块是时间上下文编码器( TCE ),它利用多头注意力机制来捕获提取特征之间的时间依赖关系。特别地,多头注意力利用因果卷积对输入特征中的时间关系进行建模。使用三个公共数据集来评估提出的AttnSleep模型的性能。_an attention-based deep learning approach for sleep stage classification wit

推荐文章

热门文章

相关标签