当前位置: 首页 > wzjs >正文

深圳商城网站设计电话手机淘宝客网站建设

深圳商城网站设计电话,手机淘宝客网站建设,青岛本地招聘网站,运城盐湖区姚孟信通网站开发中心文章目录 一、Delay 函数1.1 两个 Delay 函数1.2 Delay 函数使用示例 二、空闲线程及其钩子函数2.1 介绍2.2 代码解析2.3 使用空闲线程钩子函数 三、调度算法3.1 重要概念3.2 调度算法3.3 调度器钩子函数 一、Delay 函数 1.1 两个 Delay 函数 有 3 个 Delay 函数:…

文章目录

  • 一、Delay 函数
    • 1.1 两个 Delay 函数
    • 1.2 Delay 函数使用示例
  • 二、空闲线程及其钩子函数
    • 2.1 介绍
    • 2.2 代码解析
    • 2.3 使用空闲线程钩子函数
  • 三、调度算法
    • 3.1 重要概念
    • 3.2 调度算法
    • 3.3 调度器钩子函数

一、Delay 函数

1.1 两个 Delay 函数

有 3 个 Delay 函数:

  • rt_thread_delay():以系统时钟节拍为单位,当前线程会阻塞让出 CPU 资源
  • rt_thread_mdelay():以 ms 为单位,当前线程会阻塞让出 CPU 资源
  • rt_hw_us_delay():以 us 为单位,当前线程不会阻塞,这个函数是"死等“指定时间

这 3 个函数原型如下:

rt_err_t rt_thread_delay(rt_tick_t tick); 
rt_err_t rt_thread_mdelay(rt_int32_t ms);
void rt_hw_us_delay(rt_uint32_t us);

系统时钟节拍是 RT-Thread 定时器的最小精度
1 OS Tick = 1/RT_TICK_PER_SECOND 秒RT_TICK_PER_SECOND 值在 rtconfig.h 文件中定义

rt_thread_mdelay 也是只能是时钟节拍的整数倍,使用 rt_thread_mdelay 可移植性更

在实际应用中,可以通过前 2 个延时函数挂起当前线程,让出 CPU。

1.2 Delay 函数使用示例

本节代码为:RT-Thread_06_taskdelay。

本程序会创建 2 个线程:

  • Task1:
    • 高优先级
    • 设置变量 flag 为 1,然后调用 rt_thread_mdelay();rt_hw_us_delay();
    • rt_thread_mdelay() 会让出 CPU
    • rt_hw_us_delay() 不会让出 CPU
  • Task2:
    • 低优先级
    • 设置变量 flag 为 0

程序一些开头的定义:

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>#define THREAD_PRIORITY         15  //设置线程优先级
#define THREAD_STACK_SIZE       512 //设置线程栈大小
#define THREAD_TIMESLICE        15  //设置线程时间片大小static struct rt_thread *thread1;   //定义线程1句柄指针
static struct rt_thread *thread2;   //定义线程2句柄指针static volatile int flag = 0;

main 函数代码如下:

int main(void)
{/* 创建动态线程thread1,优先级为 THREAD_PRIORIT-1 = 14 */thread1 = rt_thread_create("thread1",          //线程名字thread1_entry,         //入口函数(void *)thread1_name,  //入口函数参数THREAD_STACK_SIZE,     //栈大小THREAD_PRIORITY-1,     //线程优先级THREAD_TIMESLICE);     //线程时间片大小/* 判断创建结果,再启动线程1 */if (thread1 != RT_NULL)rt_thread_startup(thread1);				   /* 创建动态线程thread2,优先级为 THREAD_PRIORIT = 15 */thread2 = rt_thread_create("thread2",          //线程名字thread2_entry,         //入口函数(void *)thread2_name,  //入口函数参数THREAD_STACK_SIZE,     //栈大小THREAD_PRIORITY,       //线程优先级THREAD_TIMESLICE);     //线程时间片大小/* 判断创建结果,再启动线程2 */if (thread2 != RT_NULL)rt_thread_startup(thread2);		return 0;
}

Thread1 的代码中使用条件开关来选择延时函数,把 #if 1 改为 #if 0 就可以使用
rt_hw_us_delay,代码如下:

/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{const char *thread_name = parameter;/* 线程1 */while(1){/* 打印线程的信息 */rt_kprintf(thread_name);flag = 1;#if 1		rt_thread_mdelay(50);
#else		rt_hw_us_delay(50000);
#endif	}
}

Thread2 的代码如下:

/* 线程2的入口函数 */
static void thread2_entry(void *parameter)
{const char *thread_name = parameter;/* 线程1 */while(1){/* 打印线程的信息 */rt_kprintf(thread_name);flag = 0;}
}

使用 Keil 的逻辑分析观察 flag 变量的 bit 波形,如下:

  • 使用 rt_thread_mdelay() 时,才会出现电平变化
    在这里插入图片描述
  • 使用 rt_hw_us_delay() 时,线程 1 会一直占用 CPU,线程 2 无法执行,不会出现电平变化
    在这里插入图片描述

二、空闲线程及其钩子函数

2.1 介绍

在 RT-Thread_03_delete_task 的实验里,我们提到空闲线程(Idle 线程)的作用:释放被删除的线程的内存。

除了上述目的之外,为什么必须要有空闲线程?

一个良好的程序,它的线程都是事件驱动的:平时大部分时间处于挂起状态。

有可能我们自己创建的所有线程都无法执行,但是调度器必须能找到一个可以运行的线程:所以,要提供空闲线程。

  • 空闲线程优先级最低:它不能阻碍用户线程运行
  • 空闲线程要么处于就绪态,要么处于运行态,永远不会挂起

空闲线程的优先级为最低,这意味着一旦某个用户的线程变为就绪态,那么空闲线程马上被切换出去,让这个用户线程运行。

在这种情况下,我们说用户线程"抢占"(pre-empt)了空闲线程,这是由调度器实现的。

要注意的是:如果某个线程被删除,那么需要确保后面空闲线程有机会执行,否则就
无法释放被删除线程的内存。

我们可以添加一个空闲线程的钩子函数,空闲线程的循环每执行一次,就会调用一次钩子函数。钩子函数的作用有这些:

  • 执行一些低优先级的、后台的、需要连续执行的函数
  • 测量系统的空闲时间:空闲线程能被执行就意味着所有的高优先级线程都停止了,所以测量空闲线程占据的时间,就可以算出处理器占用率
  • 让系统进入省电模式:空闲线程能被执行就意味着没有重要的事情要做,当然可以进入省电模式了。

2.2 代码解析

空闲线程的代码在文件 src\idle.c 中。

创建空闲线程的代码如下:

void rt_thread_idle_init(void)
{/* initialize thread */rt_thread_init(&idle, "tidle",rt_thread_idle_entry, RT_NULL,&rt_thread_stack[0], sizeof(rt_thread_stack), RT_THREAD_PRIORITY_MAX - 1,32);/* startup */rt_thread_startup(&idle);
}

空闲任务的入口函数如下:

  • 用户可以提供多个钩子函数:idle_hook_list[i],如果提供了就会被调用
  • 清理工作:rt_thread_idle_excute
static void rt_thread_idle_entry(void *parameter)
{while (1){#ifdef RT_USING_IDLE_HOOKrt_size_t i;for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++){if (idle_hook_list[i] != RT_NULL){idle_hook_list[i]();}}
#endifrt_thread_idle_excute();
#ifdef RT_USING_PMrt_system_power_manager();
#endif}
}

空闲线程的主要工作是调用 rt_thread_idle_excute() 来清理线程:

  • 那些使用的 rt_thread_create() 函数创建的线程,退出时都被放在 rt_thread_defunct 链表里
  • 从链表里把它们逐个取出来
  • 释放栈
  • 释放线程控制块

代码如下:
在这里插入图片描述

2.3 使用空闲线程钩子函数

在 src/idle.c 中,可以看到如下代码:

在这里插入图片描述

所以使用空闲线程钩子函数的前提是:

  • rt-config.h 里定义宏 RT_USING_IDLE_HOOK
  • 使用 rt_thread_idle_sethook 函数,设置钩子函数

在这里插入图片描述

要删除钩子函数,使用 rt_thread_idle_dehook 函数。

在这里插入图片描述

三、调度算法

3.1 重要概念

这些知识在前面都提到过了,这里总结一下。

正在运行的线程,被称为"正在使用处理器",它处于运行状态。在单处理器系统中,任何时间里只能有一个线程处于运行状态。

非运行状态的线程,它处于这 4 中状态之一:初始、就绪、挂起、关闭。

就绪态的线程,可以被调度器挑选出来切换为运行状态,调度器永远都是挑选最高优先级的就绪态线程并让它进入运行状态

挂起状态的线程,它在等待"事件",当事件发生时线程就会进入就绪状态。

事件分为两类:时间相关的事件、同步事件。

所谓时间相关的事件,就是设置超时时间:在指定时间内阻塞,时间到了就进入就绪状态。使用时间相关的事件,可以实现周期性的功能、可以实现超时功能。

同步事件就是:某个线程在等待某些信息,别的线程或者中断服务程序会给它发送信息。

怎么"发送信息"?方法很多,有:信号量(semaphores)、互斥量(mutexe)、事件集 (event)等。

这些方法用来发送同步信息,比如表示某个外设得到了数据。

3.2 调度算法

RT-Thread 的调度算法为基于优先级调度基于时间片轮转调度共存的策略。

RT-Thread 内核中存在多个线程优先级,同一个线程优先级下可以有多个线程。

优先级数目在 rtconfig.h 中以宏定义的方式配置:

#define RT_THREAD_PRIORITY_MAX 32

系统中可能有多个线程,它们的优先级可能相同、可能不同,RT-Thread 采用的调度策略是:

  • 可抢占:高优先级的就绪线程会“立刻”抢占低优先级的线程;
  • 时间片轮转:同优先级别的就绪线程,依次运行

3.3 调度器钩子函数

在整个系统运行过程中,会不断地切换线程:这由 rt_schedule()来实现。

我们还可以提供一个调度器的钩子函数,在 rt_schedule() 切换线程时它会调用该钩子函数:

  • 用户实现钩子函数,原型为 void hook_of_scheduler(struct rt_thread* from, struct rt_thread* to)
  • 使用 rt_scheduler_sethook 设置钩子函数

rt_schedule() 代码如下:

在这里插入图片描述

本节代码为:RT-Thread_07_scheduler,main 函数代码如下:

int main(void)
{/* 设置调度器钩子 */rt_scheduler_sethook(hook_of_scheduler);/* 创建动态线程thread1,优先级为 THREAD_PRIORIT-1 = 14 */thread1 = rt_thread_create("thread1",          //线程名字thread1_entry,         //入口函数(void *)thread1_name,  //入口函数参数THREAD_STACK_SIZE,     //栈大小THREAD_PRIORITY-1,     //线程优先级THREAD_TIMESLICE);     //线程时间片大小/* 判断创建结果,再启动线程1 */if (thread1 != RT_NULL)rt_thread_startup(thread1);				   /* 创建动态线程thread2,优先级为 THREAD_PRIORIT = 15 */thread2 = rt_thread_create("thread2",          //线程名字thread2_entry,         //入口函数(void *)thread2_name,  //入口函数参数THREAD_STACK_SIZE,     //栈大小THREAD_PRIORITY,       //线程优先级THREAD_TIMESLICE);     //线程时间片大小/* 判断创建结果,再启动线程2 */if (thread2 != RT_NULL)rt_thread_startup(thread2);		return 0;
}

钩子函数内容如下:

static void hook_of_scheduler(struct rt_thread* from, struct rt_thread* to)
{rt_kprintf("Thread:%s -->  Thread:%s \r\n", from->name, to->name);
}

线程 1、线程 2 代码如下:

/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{const char *thread_name = parameter;/* 线程1 */while(1){/* 打印线程的信息 */rt_kprintf(thread_name);rt_thread_mdelay(10);}
}/* 线程2的入口函数 */
static void thread2_entry(void *parameter)
{const char *thread_name = parameter;/* 线程1 */while(1){/* 打印线程的信息 */rt_kprintf(thread_name);}
}

程序运行时:

  • 优先级高的线程 1 会先运行
  • 线程 1 调用 rt_thread_mdelay() 后挂起,将切换到线程 2
  • 切换时,钩子函数被调用,它打印调度信息

在这里插入图片描述


文章转载自:

http://Ofru9GOS.Lxhgj.cn
http://Qc4YbvjU.Lxhgj.cn
http://dv4UrHnR.Lxhgj.cn
http://6meirW2c.Lxhgj.cn
http://KNJKJntJ.Lxhgj.cn
http://DKDwKspG.Lxhgj.cn
http://vYrHbUjT.Lxhgj.cn
http://XmYBLHQb.Lxhgj.cn
http://hqAi91Ts.Lxhgj.cn
http://6L6GyDDo.Lxhgj.cn
http://5EguF6Ng.Lxhgj.cn
http://XfvDcTze.Lxhgj.cn
http://pa46D5qA.Lxhgj.cn
http://zlBiGAAl.Lxhgj.cn
http://Arwxhe3b.Lxhgj.cn
http://4v4q4Gmo.Lxhgj.cn
http://LaH40oIV.Lxhgj.cn
http://LF0tkhc3.Lxhgj.cn
http://Pn1Gk6KP.Lxhgj.cn
http://OK0tGw2n.Lxhgj.cn
http://62GQG86O.Lxhgj.cn
http://X69mB3ud.Lxhgj.cn
http://AIXeKdVQ.Lxhgj.cn
http://qAUU45yD.Lxhgj.cn
http://kYAbuCo4.Lxhgj.cn
http://JUqHIpxF.Lxhgj.cn
http://fV5R1nFn.Lxhgj.cn
http://znte39U5.Lxhgj.cn
http://Rw3tTgBg.Lxhgj.cn
http://WdrTt6tg.Lxhgj.cn
http://www.dtcms.com/wzjs/662765.html

相关文章:

  • 网站后台无法上传图片公司倒闭了员工怎么赔偿
  • 百度网站提交入口杭州公司的网站建设公司
  • 北屯网站建设深圳建网站 (报价)
  • 公司网站建设教程码上游二维码制作
  • 昆明网站设计多少钱wordpress本地播放器
  • 南宁网站建设公司哪里windows server 2003 怎么给网站做域名解析
  • wordpress默认主体设置北京正规seo搜索引擎优化价格
  • 专门做国外网站徐州百度快照优化
  • mvc5网站开发之美电子版传播性wordpress主题
  • 深圳建设集团股份有限公司品牌关键词排名优化怎么做
  • 湖北 商城网站建设多少钱外贸人才网最新招聘信息
  • 怎么在网站后台删除图片站长统计ios
  • 哪些网站容易做怎么看关键词的搜索量
  • 企业网站管理的含义及内容中国建设工程信息网官网建造师查询
  • 郑州网站zhi zuo建设银行山东 2015招聘网站
  • 怎么做招聘网站万站网
  • 庆阳手机网站设计wordpress电子商城模板
  • 地方旅游网站开发莱芜网站设计
  • 建立网站建站程序社交网站图片展示
  • 网站建设公司网站模板下载有些网站怎么经常换域名
  • 建设小型网站价钱网站设计论文题目
  • 嘉兴建设中学网站济宁专业网站制作公司
  • 百度云wordpress怎么搭建网站做一名优秀网站设计师计划
  • 通过wordpress建站wordpress 主题配置
  • 如何建设一个静态网站个人怎样做旅游网站
  • 外贸网站建设公司市场有什么教做甜品的网站
  • 网站建设与维护就业前景html网站欣赏
  • 榆林北京网站建设淘宝seo是指什么
  • 永康网站建设制作室内设计培训班排行榜学校
  • 高校资源网网站建设方案seo优化系统哪个好