嵌入式实时操作系统的设计与开发(调度策略学习)

将调度分为两层,上层为策略,下层为机制,并且采用策略与机制分离的设计原则,可以方便灵活地扩展调度策略,而不改变底层的调度机制。

调度策略就是如何确定线程的CPU、优先级prio等参数,线程是按照FIFO,还是分时策略来调度。对某些线程要特殊调度处理,然后根据相应操作来初始化线程。一种策略就对应一种线程。

线程调度分层结构

在这里插入图片描述

调度策略本质就是调度算法,即确定任务执行顺序的规则,调度策略目前包括通用策略、分时策略、周期策略和RM策略,用户还可以自行扩展新的调度策略。

用户创建线程时,需要指定某种调度策略,并找到该调度策略对应的策略控制块,再为TCB成员赋值。

调度策略分类

  1. 普通线程(通用策略创建的线程)。这种线程,需要人为指定CPU、优先级信息,通过acoral_create_thread创建。
  2. 分时线程(分时策略创建的线程)。aCoral支持相同优先级的线程,对于相同优先级的线程,默认采用FIFO的方式调度,因此,当用户需要以分时的方式和其他线程共享CPU资源时,可以将该线程设置为分时线程。若用分时调度策略创建线程,应注意以下两点:
    (1)只存在相同优先级的分时策略,不同优先级线程之间不存在所谓的分时策略,它们是按优先级抢占策略来调度的。
    (2)必须都是分时线程。
  3. 周期线程(周期策略创建的线程)。这种线程需要每隔一个固定时间就要执行一次,如信号采集系统有一个采样周期,每隔一段时间就要采集一路信号。
  4. RM线程(RM策略创建的线程)。RM是一种可以满足任务截止时间的强实时调度算法,这种策略需要周期性线程策略支持。在配置成支持RM的线程策略,就必须同时配置支持周期性策略。
  5. POSIX线程(POSIX策略创建的线程)。POSIX线程属于非实时线程,也是一个标准,这类线程的主要特点是越公平越好。让aCoral支持POSIX标准有两个出发点,一是实现最大公平,二是实现POSIX标准。为了实现最大公平,这种线程又有了一个自己的调度算法:电梯调度算法。

描述调度策略

typedef struct{acoral_list_t list; //策略链表结点,用于将策略挂到策略链表上去,用于把各个调度策略串到一个链表上,创建线程找策略的时候去这个链表上,根据策略名找,有几个策略就有几个结点acoral_u8 type; //策略类型,比如COMM_id (*policy_thread_init)(acoral_thread_t *, void (*route)(void *args), void *,void *); //策略线程初始化函数,用于确定线程的CPU、优先级等参数。void (*policy_thread_release)(acoral_thread_t *); //某种策略的释放函数,用于消灭线程时调用void (*delay_deal)(void); //与延时相关的处理函数,如period、slice等策略都要用到类似的延时机制。char *name; //用于传递某种调度策略所需要的参数。每种策略对应一种数据结构,用来保存线程的参数,比如普通策略的参数只有CPU、prio。
}acoral_sched_policy_t;
//普通线程调度相关的数据
typedef struct{unsigned char prio; unsigned char prio_type; //优先级类型,有BASE_PRIO,根据系统需要在创建线程时进行调整;ABSOLUTE,表示优先级设定是多少就多少
}comm_policy_data_t
//周期策略数据块
typedef struct{unsigned char prio;unsigned char prio_type;unsigned int time;//线程周期,单位毫秒
}period_polciy_data_t;

查找调度策略

当用户想根据某种调度策略创建线程时,须根据TCB的policy成员值从策略控制块链表中查找相应的结点,将信息取出赋值给TCB成员。

acoral_list_t policy_list;
acoral_sched_policy_t *acoral_get_policy_ctrl(unsigned char type){acoral_list_t *tmp,*head;acoral_sched_policy_t *policy_ctrl;head = &policy_list;tmp = head;for(tmp=head->next;tmp!=head;tmp=tmp->next){policy_ctrl = list_entry(tmp,acoral_sched_policy_t,list);if(policy_ctrl->type == type)return policy_ctrl;}return NULL;
}

当创建一个结构体变量时,该结构体变量在内存中会占据一段连续的内存空间,每个成员变量都在这个内存块中有自己的地址偏移。

结构体指针实际上是一个执行结构体内存块起始地址的指针。通过这个指针,可以访问结构体内存块中的各个成员变量。

  1. 内存布局:结构体的成员变量在内存中是按照它们在结构体定义中的顺序排列的,成员变量之间是连续存储的。
  2. 操作符->,结构体指针用->来访问结构体成员
struct Point{int x;int y;
};struct Point p1;
struct Point *ptr = &p1;ptr->x = 10;
ptr->y = 20;p1.x = 5;
p1.y = 15;

注册调度策略

若要扩展新的调度策略并且生效,须进行注册,只有注册后,用户才能通过此策略创建特定类型的线程。
注册就是将用户自己定义的调度策略挂载到策略控制链表上,放在队尾。

void acoral_register_sched_policy(acoral_sched_policy_t *policy){acoral_list_add2_tail(&policy->list, &policy_list);
}

通用调度策略是在什么时候注册的呢?
在进行通用调度策略初始化comm_policy_init()时注册

acoral_sched_policy_t comm_policy;
void comm_policy_init()
{comm_policy.type = ACORAL_SCHED_POLICY_COMM;comm_policy.policy_thread_init = comm_policy_thread_init;comm_policy.policy_thread_release = NULL;comm_policy.delay_deal = NULL;comm_policy.name = "comm";acoral_register_ched_policy(&comm_policy);
}
acoral_list_t period_delay_queue; //周期线程专用延时队列,只要是周期线程,就会被挂载到这个队列上,延时时间就是周期,每次周期过后重新挂载
acoral_sched_policy_t period_policy;
void period_policy_init(void)
{acoral_init_list(&period_delay_queue);period_policy.type=ACORAL_SCHED_POLICY_PERIOD;period_policy.policy_thread_init=period_policy_thread_init;period_policy.policy_thread_release=period_policy_thread_release;period_policy.delay_deal=period_delay_deal;period_policy.name="period";acoral_register_sched_policy(&period_policy);
}

通用调度策略初始化又是在什么时候被调用的呢?

void sched_policy_init()
{acoral_init_list(&policy_list);comm_policy_init();
#ifdef CFG_THRD_PERIODperiod_policy_init();
#endif
}
void acoral_thread_sys_init()
{acoral_sched_mechanism_init();acoral_sched_policy_init();
}
void acoral_sched_machanism_init()
{acoral_thread_pool_init();acoral_thread_runqueue_init();acoral_init_list(&acoral_threads_queue); //全局所有线程队列
}
acoral_pool_ctr_ acoral_thread_pool_ctrl;
void acoral_thread_pool_init()
{acoral_thread_pool_ctrl.type = ACORAL_RES_THREAD;acoral_thread_pool_ctrl.size = sizeof(acoral_thread_t);if(CFG_MAX_THREAD > 20)acoral_thread_pool_ctrl.num_per_pool = 20;elseacoral_thread_pool_ctrl.num_per_pool = CFG_MAX_THREAD;acoral_thread_pool_ctrl.max_pools = CFG_MAX_THREAD/acoral_thread_pool_ctrl.num_per_pool;acoral_pool_ctrl_init(&acoral_thread_pool_ctrl);
}
void acoral_pool_ctrl_init(acoral_pool_ctrl_t *pool_ctrl)
{unsigned int size;pool_ctrl->free_pools = &pool_ctrl->list[0];pool_ctrl->pools = &pool_ctrl->list[1];pool_ctrl->num = 0;acoral_init_list(pool_ctrl->pools);acoral_init_list(pool_ctrl->free_pools);//调整pool的对象个数最大化利用分配了的内存size = acoral_malloc_adjust_size(pool_ctrl->size * pool_ctrl->num_per_pool);if (size < pool_ctrl->size){pool_ctrl->num_per_pool = 0;}else{pool_ctrl->num_per_pool = size / pool_ctrl->size;acoral_create_pool(pool_ctrl); // 先创建一个资源池,后面如果一个池子不够了,那在不超过这类资源的max_pool的条件下再创建新的池子}
}
void acoral_thread_runqueue_init()
{acoral_rdy_queue_t *rdy_queue;rdy_queue = &acoral_ready_queues;acoral_prio_queue_init(rdy_queue);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/108711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode刷题(数据结构)】:检查两颗树是否相同

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true 输入&#xff1a;p [1,2], q [1,…

05_51单片机led流水线的实现

1:step创建一个新的项目并将程序烧录进入51单片机 以下是51单片机流水线代码的具体实现 #include <REGX52.H>void Delay500ms() //11.0592MHz {unsigned char i, j, k;i 4;j 129;k 119;do{do{while (--k);} while (--j);} while (--i); }void main(){while(1){P1 0…

【性能测试篇1】初识性能测试

目录 性能测试定义 性能测试和功能测试有什么区别 测试工具上面&#xff1a; 特殊业务场景下&#xff1a; 性能测试常见概念&#xff1a; ①用户相关&#xff1a; 1.1并发用户数&#xff1a; 1.2在线用户数&#xff1a; 1.3系统用户数量&#xff1a; ②响应时间相关&…

SpringMVC之国际化上传下载

spring项目中的国际化 1&#xff09;提供中英两种资源文件 i18n_en_US.properties i18n_zh_CN.properties 2&#xff09;配置国际化资源文件&#xff08;在spring配置文件中添加&#xff0c;例如spring-mvc.xml&#xff09; <bean id"messageSource" class&quo…

通达OA 2016网络智能办公系统 handle.php SQL注入漏洞

一、漏洞描述 北京通达信科科技有限公司通达OA2016网络智能办公系统 handle.php 存在sql注入漏洞&#xff0c;攻击者可利用此漏洞获取数据库管理员权限&#xff0c;查询数据、获取系统信息&#xff0c;威胁企业单位数据安全。 二、网络空间搜索引擎查询 fofa查询 app"T…

【STL】平衡二叉树

前言 对于之前普通的二叉搜索树&#xff0c;其搜索的效率依靠树的形状来决定&#xff0c;如下&#xff1a; 可以看到 A图 中的树比较彭亨&#xff0c;搜索一个元素的效率接近 O(logN) &#xff1b;而 B图 中的形状也符合搜索二叉树&#xff0c;但是很不平衡&#xff0c;这时的…

框架篇

一、Spring中的单例Bean是线程安全的吗 二、AOP相关面试题 三、Spring中的事务 四、Spring中事务失效的场景有 五、Spring bean的生命周期 六、Spring的循环依赖 七、SpringMVC的执行流程 八、自动配置原理 九、Spring框架常见的注解 十、Mybatis的执行流程 十一、MyBatis延迟加…

(转)tinymce-vue使用教程

一、资源下载 npm install tinymce -S //当前版本^5.1.1 npm install tinymce/tinymce-vue -S //当前版本^3.0.1二、安装语言包 资源下载后,在 node_modules 中找到 tinymce/skins 目录&#xff0c;然后将 skins 目录拷贝到 static 目录下,(PS: 如果是使用 vue-cli 3.x 构建…

前端开发tips

vue配置启动项目自动打开浏览器 打开package.json找到启动命令npm run dev 跟npm run serve(这两种命令都可以) 后面增加 --open Vue项目设置路径src目录别名为 Vue2 编辑vue.config.js内容如下&#xff1a; const { defineConfig } require(vue/cli-service)const path…

STM32Cube高效开发教程<基础篇>(六)----FSMC连接TFT-LCD屏

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    本专栏博客参考《STM32Cube高效开发教程(基础篇)》,有意向的读者可以购买正版书籍辅助学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。 一、 FSMC连接…

LeetCode34 在排序数组中寻找元素的第一个和最后一个位置

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/wangjiaqi333/article/details/124526112 直观的思路肯定是从前往后遍历一遍。用两个变量记录第一次和最后一次遇见target的下标&#xff0c;但这个方法的时间复杂度为O(n)&#xff0c;没有利用到数组升序排列的条件…

小程序-uni-app:将页面(html+css)生成图片/海报/名片,进行下载 保存到手机

一、需要描述 本文实现&#xff0c;uniapp微信小程序&#xff0c;把页面内容保存为图片&#xff0c;并且下载到手机上。 说实话网上找了很多资料&#xff0c;但是效果不理想&#xff0c;直到看了一个开源项目&#xff0c;我知道可以实现了。 本文以开源项目uniapp-wxml-to-can…

前端技术-并发请求

并发请求 代码解释 定义了一个函数 concurRequest&#xff0c;用于并发请求多个 URL 并返回它们的响应结果。 function concurRequest(urls, maxNum) {return new Promise((resolve, reject) > {if (urls.length 0) {resolve([]);return;}const results [];let index …

【vue2高德地图api】01-创建应用,获取key值

系列文章目录 【vue2高德地图api】视频效果&#xff08;手机端&#xff09;先看这里 文章目录 系列文章目录前言创建key&#xff08;2个&#xff09;1.1进入控制台1.2进入应用1.3 创建应用1.4输入名称和类型2.1 添加key2.2 选择对应信息2.3 创建js key和服务端 key 总结 前言 …

Qt/C++编写物联网组件/支持modbus/rtu/tcp/udp/websocket/mqtt/多线程采集

一、功能特点 支持多种协议&#xff0c;包括Modbus_Rtu_Com/Modbus_Rtu_Tcp/Modbus_Rtu_Udp/Modbus_Rtu_Web/Modbus_Tcp/Modbus_Udp/Modbus_Web等&#xff0c;其中web指websocket。支持多种采集通讯方式&#xff0c;包括串口和网络等&#xff0c;可自由拓展其他方式。自定义采…

排序算法-基数排序法(RadixSort)

排序算法-基数排序法&#xff08;RadixSort&#xff09; 1、说明 基数排序法与我们之前讨论的排序法不太一样&#xff0c;并不需要进行元素之间的比较操作&#xff0c;而是属于一种分配模式排序方式。 基数排序法比较的方向可分为最高位优先&#xff08;Most Significant Di…

支持语音与视频即时通讯项目杂记(一)

第一部分解释服务端的实现。 &#xff08;服务端结构&#xff09; 下面一个用于实现TCP服务器的代码&#xff0c;包括消息服务器&#xff08;TcpMsgServer&#xff09;和文件中转服务器&#xff08;TcpFileServer&#xff09;。 首先&#xff0c;TcpServer是TcpMsgServer和Tcp…

上采样相关技术

一、参考资料 上采样和上卷积的区别 怎样通俗易懂地解释反卷积&#xff1f; 卷积和池化的区别、图像的上采样&#xff08;upsampling&#xff09;与下采样&#xff08;subsampled&#xff09; [读论文]用全卷积Res网络做深度估计 对抗生成网络GAN系列——DCGAN简介及人脸图像生…

MapReduce任务个数如何影响执行效率?性能优化从这里做起

在正文开始之前&#xff0c;请先来回答一下这个问题&#xff1a; 题目&#xff1a;输入为3个文件&#xff0c;a.txt 300MB,b.txt 100MB,c.txt 58.MB&#xff0c;使用MapReduce的example程序&#xff0c;计算Wordcount&#xff0c;请问&#xff0c;应该有多少个MapTask&#xf…

算法、推理、部署,面了40多个大佬的感想

今年三月份到现在陆陆续续面了40来个人&#xff0c;有实习生&#xff0c;有校招生&#xff0c;也有来社招的大佬们。面了挺久&#xff0c;有些总结和感想&#xff0c;发出来和大家交流交流&#xff0c;也趁着这个机会为之后参与校招的同学提供一些学习方向。 我面的岗位主要是…