- 1、本文档共6页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
RTThreadRTOS应用之三线程同步
RT Thread RTOS应用之三——线程同步
实验描述:本实验学习如何使用信号量和邮箱来实现线程的同步。实验在实验二的基础上,新建两个线程:“sem_thread_entry”和“mb_thread_entry”。这两个线程分别依靠信号量(semaphore)和邮箱(mail box)来实现线程同步。实验中通过usart2接受到的数据来分别发送对应的信号量或者邮件,已完成两个线程的切换。线程的运行情况会通过finsh系统传送到电脑上,共用户观察。
信号量和邮箱相关知识的介绍:
信号量:信号量是用来解决线程同步和互斥的通用工具,和互斥量类似,信号量也可用作资源互斥访问,但信号量没有所有者的概念,在应用上比互斥量更广泛。信号量比较简单,不能解决优先级翻转问题,但信号量是一种轻量级的对象,比互斥量小巧、灵活。因此在很多对互斥要求不严格的系统中(或者不会造成优先级翻转的情况下),经常使用信号量来管理互斥资源。简而言之,信号量就是一个信号,类似于我们平常自己设定的标志。通过这个信号的状态(0或者非0)来表征当前线程的状态(是否可以运行)。每次线程申请一次信号量,信号量变量的数值会减一,反之,释放一个信号量,信号量变量的数值会加一。
邮箱:邮箱服务是实时操作系统中一种典型的任务间通信方法,通常开销比较低,效率较高,每一封邮件只能容纳固定的4字节内容(针对32位处理系统,刚好能够容纳一个指针)。这里需要注意的是,邮箱中每一封邮件的容量是有限的,因此,如果信息量小于4个字节,那么可以直接利用邮件传送信息,否则,需要利用邮件传送保存信息的变量指针。
下面开始通过实际的程序来逐步讲解信号量和邮箱的使用方法。
首先在application.c文件中定义信号量,邮箱,以及邮箱池变量
/**********************信号量、邮箱初始化**************************/
struct rt_semaphore sem;//利用静态信号量,定义信号量
struct rt_mailbox mb;//利用静态邮箱,定义邮箱
static char mailpool[128];//定义邮箱池,其决定了,邮箱可以接受多少封邮件
/******************************************************************/
其中邮箱池变量是这个邮箱的容量,因为每封邮件占用4个字节的控件,因此,本程序中的邮箱可以最多保存128/4=32封邮件。当油箱内的邮件超过这个数量的时候,新来的邮件会发送失败,并且返回相应代码。
初始化信号量和邮箱:
/******************初始化信号量和邮箱**************/
rt_sem_init(sem,sem,0,RT_IPC_FLAG_FIFO);//按照先入先出的原则申请信号狼
rt_mb_init(mb,mb,mailpool[0],sizeof(mailpool)/4,RT_IPC_FLAG_FIFO);//按照先入先出的原则,申请了一个可以存放32封邮件的邮箱
/***************************************************/
rt_sem_init()是信号量初始化函数,其中sem是之前定义的信号量指针;”sem”是信号量的名称,为了在finsh中查询;参数0是信号量初始值,如果这个数值为非0,那么不需要释放信号量,线程就可以申请到信号量。”RT_IPC_FLAG_FIFO”表示信号量的申请遵守“先到先得”的方式,即:那个线程先申请,那个线程先获得。
rt_mb_init() 是邮箱初始化函数,与上面的信号量初始化函数类似。其中mb表示邮箱指针;”mb”表示邮箱的名称;mailpool[0]表示邮箱池的首地址;sizeof(mailpool)/4表示邮箱的容量。
信号量同步线程入口:
/*******************建立信号量同步线程*****************/
rt_uint8_t sem_stack[512];
struct rt_thread sem_thread;
void sem_thread_entry(void* parameter)
{
while(1)
{
rt_kprintf(信号量同步线程开始申请信号量\n);
LED1(ON);
rt_sem_take(sem,RT_WAITING_FOREVER);//申请信号量,并且无限等待
rt_kprintf(接收到信号量\n);
LED1(OFF);
rt_thread_delay(50);//延迟该线程50m
文档评论(0)