嵌入式实时操作系统的设计与开发 (线程操作学习)
在aCoral操作系统中,线程退出采用了和Linux一样的方式,线程函数不用死等或显示调用退出相关函数,也就是说用户不用担心函数执行完后的事情。
uc/OS II任务函数与退出
void test(void *ptr){Do_something();while(1);
}void test(void *ptr){Do_something();EXIT();
}
void acoral_thread_exit(){acoral_kill_thread(acoral_cur_thread);
}
typedef struct{acoral_res_t res; //event也是一种资源unsigned char type; //ACORAL_EVENT_SEM或ACORAL_EVENT_MUTEXint count; //acoral_list_t wait_queue;char *name;void *data;
}acoral_evt_t;void acoral_kill_thread(acoral_thread_t *thread){acoral_evt_t *evt;acoral_enter_critical();if(thread->state & ACORAL_THREAD_STATE_SUSPEND){evt = thread->evt;if(thread->state & ACORAL_THREAD_STATE_DELAY){acoral_list_del(&thread->waiting);}else{if(evt!=NULL){acoral_evt_queue_del(thread);}}}acoral_unrdy_thread(thread); //将线程从就绪队列中取下acoral_release_thread1(thread);acoral_exit_critical();acoral_sched();
}
如果线程处于挂起状态,则需要从相关链表中取下。
- 如果是延时挂起,则从延时队列取下。
- 如果是事件等待,则从事件队列取下。
void acoral_unrdy_thread(acoral_thread_t *thread){if(!(ACORAL_THREAD_STATE_READY&thread->state))return;acoral_rdyqueue_del(thread);
}
void acoral_rdyqueue_del(acoral_thread_t *thread)
{acoral_rdy_queue_t *rdy_queue;rdy_queue = &acoral_ready_queues;acoral_prio_queue_del(rdy_queue, thread->prio, &thread->ready);thread->state &= ~ACORAL_THREAD_STATE_READY;thread->state &= ~ACORAL_THREAD_STATE_RUNNING;thread->state |= ACORAL_THREAD_STATE_SUSPEND;acoral_set_need_sched(true);
}
extern int daemon_id;
void acoral_release_thread1(acoral_thread_t *thread){acoral_list_t *head;acoral_thread_t *daem;thread->sate = ACORAL_THREAD_STATE_EXIT;head = &acoral_res_release_queue;acoral_list_add2_tail(&thread->waiting, head);daem = (acoral_thread_t *)acoral_get_res_by_id(daemon_id);acoral_rdy_thread(daem);
}
将线程设置为退出状态,如果是当前线程,则只能是EXIT状态,表明还不能释放该线程的资源,如TCB,堆栈,因为仅管线程要退出了,还没有走到HAL_SWITCH_TO函数,该函数还需要堆栈。
void daem(void *args)
{acoral_thread_t *thread;acoral_list_t *head, *tmp, *tmp1;head = &acoral_res_release_queue;while(1){for(tmp=head->next;tmp!=head;){tmp1 = tmp->next;acoral_enter_critical();thread = list_entry(tmp, acoral_thread_t, waiting);acoral_list_del(tmp);acoral_exit_critical();tmp = tmp1;if(thread->state == RELEASE){acoral_release_thread((acoral_res_t *)thread);}else{acoral_enter_critical();tmp1 = head->prev;acoral_list_add2_tail(&thread->waiting, head); /**/acoral_exit_critical();}}acoral_suspend_self();}
}
挂起线程
操作系统在运行过程中,有时需要挂起某个线程,例如,当某一线程运行时需要请求某一资源,而该资源正在被其它线程所占用,此时,用户线程需要挂起自己。
void acoral_unrdy_thread(acoral_thread_t *thread){if(!(ACORAL_THREAD_STATE_READY&thread->state))return;acoral_rdyqueue_del(thread);
}
void acoral_rdyqueue_del(acoral_thread_t *thread)
{acoral_rdy_queue_t *rdy_queue;rdy_queue = &acoral_ready_queues;acoral_prio_queue_del(rdy_queue, thread->prio, &thread->ready);thread->state &= ~ACORAL_THREAD_STATE_READY;thread->state &= ~ACORAL_THREAD_STATE_RUNNING;thread->state |= ACORAL_THREAD_STATE_SUSPEND;/*设置线程所在的核可调度*/acoral_set_need_sched(true);
}
void acoral_prio_queue_del(acoral_rdy_queue_t *array, unsigned char prio, acoral_list_t *list){acoral_list_t *queue;acoral_list_t *head;queue = array->queue + prio;head = queue;array->num--;acoral_list_del(list);if(acoral_list_empty())acoral_clear_bit(prio,array->bitmap);
}
任务挂起接口用到的地方很多,只要牵涉任务等待都会调用该函数。
那如何区分用户是调用acoral_suspend_thread(),还是调用acoral_delay_self()导致线程suspend的呢?
很简单,看线程TCB的waiting成员是否为空,如果因为等待时间或资源导致suspend,其waiting肯定挂在一个队列上,否则是直接调用acoral_suspend_thread()导致的suspend。
改变线程优先级
当多个线程互斥地访问某一共享资源的时候,可能导致优先级反转,优先级反转将造成实时调度算法的不确定性,进而影响系统实时性的确保。
解决优先级反转的方法是优先级继承和优先级天花板,而使用这两种方式的时候,需要动态改变线程优先级。
acoral描述线程优先级时,采用的是优先级队列,每个优先级是一个链表,因此改变优先级不是简单地将线程TCB的prio变量更改,最终要通过acoral_thread_change_prio()实现将线程挂到要设置的优先级的链表上去。
void acoral_thread_change_prio(acoral_thread_t *thread, unsigned int prio){acoral_enter_critical();if(thread->state&ACORAL_THREAD_STATE_READY){acoral_rdyqueue_del(thread);thread->prio = prio;acoral_rdyqueue_add(thread);}elsethread->prio = prio;acoral_exit_critical();
}
如果线程处于就绪态,则将线程从就绪队列取下,改变优先级,再次将线程挂到就绪队列。
调度策略时间处理函数
系统启动后,晶体振荡器源源不断地产生周期性信号,通过设置,晶体振荡器可以为系统产生稳定的Ticks,也称为心跳,Tick是系统的时基,也是系统中最小的时间单位,Tick的大小可以根据晶体振荡器的精度和用户的需求进行设置。
每当产生一个Tick,都对应着一个时钟中断服务程序ISR。
时钟中断服务程序的具体是acoral_ticks_entry()
void acoral_tciks_entry(int vector){tick++;if(acoral_start_sched==true){time_delay_deal();acoral_policy_delay_deal();timeout_delay_deal();}
}
acoral_list_t time_delay_queue; //线程延时队列,调用线程delay相关函数的线程都会被加到这个队列上,等待一段具体的时间后被重新唤醒
void time_delay_deal(){acoral_list_t *tmp,*tmp1,*head;acoral_thread_t *thread;head = &time_delay_queue;if(acoral_list_empty(head))return;thread = list_entry(head->next,acoral_thread_t,waiting);thread->delay--;for(tmp=head->next;tmp!=head;){thread = list_entry(tmp,acoral_thread_t,waiting);if(thread->delay > 0)break;tmp1= tmp->next;acoral_list_del(&thread->waiting);tmp=tmp1;thread->state &= ~ACORAL_THREAD_STATE_DELAY;acoral_rdy_thread(thread);}
}
void acoral_policy_delay_deal(){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->delay_deal!=NULL)policy_ctrl->delay_deal();}
}
acoral_list_t period_delay_queue;//周期线程专用延时队列
void period_delay_deal()
{acoral_list_t *tmp,*tmp1,*head;acoral_thread_t *thread;period_private_data_t *private_data;head = &period_delay_queue;if(acoral_list_empty(head))return;thread = list_entry(head->next, acoral_thread_t, waiting);thread->delay--;for(tmp=head->next;tmp!=head;){thread = list_entry(tmp,acoral_thread_t,waiting);if(thread->delay > 0)break;private_data = thread->private_data;tmp1 = tmp->next;acoral_list_del(&thread->waiting);tmp = tmp1;if(thread->state&ACORAL_THREAD_SUSPEND){thread->stack=(unsigned int *)((char *)thread->stack_buttom+thread->stack_size-4);HAL_STACK_INIT(&thread->stack,private_data->route,period_thread_exit,private_data->args);acoral_rdy_thread(thread);}period_thread_delay(thread,private_data->time);}
}
相关文章:
嵌入式实时操作系统的设计与开发 (线程操作学习)
在aCoral操作系统中,线程退出采用了和Linux一样的方式,线程函数不用死等或显示调用退出相关函数,也就是说用户不用担心函数执行完后的事情。 uc/OS II任务函数与退出 void test(void *ptr){Do_something();while(1); }void test(void *ptr)…...

竞赛 深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv
文章目录 0 前言1 课题背景2 实现效果3 DeepSORT车辆跟踪3.1 Deep SORT多目标跟踪算法3.2 算法流程 4 YOLOV5算法4.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 *…...

【RTOS学习】同步与互斥 | 队列
🐱作者:一只大喵咪1201 🐱专栏:《RTOS学习》 🔥格言:你只管努力,剩下的交给时间! 同步与互斥 | 队列 🍉同步与互斥🍦同步🍦互斥 🍉队…...
Python订单生成器+队列+异步提高性能和容错
以下代码实现了一个订单生成器,使用 asyncio 和 aioredis 库实现了高并发地生成订单,并将新增订单异步更新到数据库。具体实现流程如下: 初始化 OrderGenerator 类。传入 Redis 服务器地址和并发数,在初始化函数中设置并发数和一…...
理德名人故事:全球投资之父-约翰.邓普顿
说到约翰‧邓普顿,我们就会想到他的很多标签。比如全球投资之父、史上最成功的基金经理等等。他是邓普顿集团的创始人,一直被誉为全球最具智慧以及最受尊崇的投资者之一。福布斯资本家杂志称他为"全球投资之父"及"历史上最成功的基金经理…...

微前端三:qiankun 协作开发和上线部署
我们先看qiankun怎么上线部署: 我这边用的是yaml 文件在 rancher上部署的: base是基座,这里每个应用都是一个服务,这个还是跟之前一样并没有区别,那如何在一个域名上挂载多个服务呢? 最开始我们主要是在in…...

HTML三叉戟,标签、元素、属性各个的意义是什么?
🌟🌟🌟 专栏详解 🎉 🎉 🎉 欢迎来到前端开发之旅专栏! 不管你是完全小白,还是有一点经验的开发者,在这里你会了解到最简单易懂的语言,与你分享有关前端技术和…...

prometheus获取kubelet接口监控数据
一、前言 k8s集群的kubelet服务内部有自带的cadvisor服务用于收集k8s集群的监控数据,所以可以通过调用kubelet的接口就能获取pod的资源监控数据,在新版本的k8s中,kubelet的监控数据获取端口为10250端口,老版本的是10255端口 二、…...

国产主控应用案例:汉王电子血压计-君正开发板
2023春季新品发布会上汉王科技发布柯氏音法电子血压计产品—汉王电子血压计,继嗅觉检测盒之后再次深度布局大健康领域。 不同于当前市面上使用示波法原理的电子血压计,汉王电子血压计采用血压测量金标准中的柯氏音法,由此引领一场电子血压计领…...

万宾科技智能井盖传感器特点介绍
当谈论城市基础设施的管理和安全时,井盖通常不是第一项引人注目的话题。然而,传统井盖和智能井盖传感器之间的差异已经引起了城市规划者和工程师的广泛关注。这两种技术在功能、管理、安全和成本等多个方面存在着显著的差异。 WITBEE万宾智能井盖传感器E…...
YoloV8改进策略:SwiftFormer,全网首发,独家改进的高效加性注意力用于实时移动视觉应用的模型,重构YoloV8
文章目录 摘要论文:《SwiftFormer:基于Transformer的高效加性注意力用于实时移动视觉应用的模型》1、简介2、相关研究3、方法3.1、注意力模块概述3.2、高效的加性注意力3.3、SwiftFormer 架构4、实验4.1、实现细节4.2、基线比较4.3、图像分类4.4、目标检测和实例分割4.5、语义…...
Jupyter Notebook在指定位置打开
1、在Jupyter Notebook设置文件中修改默认路径 anconda prompt输入: jupyter notebook --generate-config 找到配置文件路径:C:\Users\Lenovo.jupyter 打开文件,修改默认路径: ## The directory to use for notebooks and kernel…...

树控件的使用
目录 1、修改树控件的基础属性: 2、准备图标 : (1)、ico后缀的图片放入当前文件路径的rc中 (2)、在Icon中添加资源,导入图片 (3)、准备HICON图标 (4&am…...
C++实现顺序栈类的定义,编写main ()函数验证顺序栈类设计的合理性
C实现顺序栈类的定义,编写main ()函数验证顺序栈类设计的合理性 以下是一个简单的C代码示例,用于实现顺序栈类的定义并编写main()函数来验证其合理性: #include <iostream> using namespace std;const int MAX_SIZE 100; // 定义栈的…...
手机直播助手软件app哪个好用?
手机直播助手软件现在可谓是多如牛毛,从上半年魔棒手机自动直播软件上线以来。几乎全国所有的科技公司都效仿魔棒手机自动直播软件兴起手机直播助手开发热。相对来说,简单的手机直播助手软件没什么技术门槛。但是手机无人直播助手软件要做精做全则很难。…...

腾讯待办宣布关停,哪款待办事项提醒APP好?
如果你之前一直使用微信中的“腾讯待办”小程序来记录待办事项并设置定时提醒,那么你就会发现腾讯待办在2023年10月16日通过其官方微信公众号、小程序发布了业务关停公告,将于2023年12月20日全面停止运营并下架,并且有导出数据的提示。 腾讯…...

【单片机毕业设计】【hj-006-7】CO、有害混合气体检测 | 空气质量检测 | 有害气体检测
一、基本介绍 项目名: 基于单片机的CO、有害混合气体检测系统设计 基于单片机的空气质量检测系统设计 基于单片机的有害气体检测系统设计 项目编号:mcuclub-hj-006-7 单片机类型:STC89C52 具体功能: 1、通过MQ-7检测CO值&#x…...

wpf主页面解析
1、 开头的网址作用 1和2都是引入命名空间的,每一个字符串代表一系列的命名空间,这样就可以不用一个一个引用了。wpf中规定有一个名称空间是可以不加名字的,xmlns不加名字是默认命名空间。 "http://schemas.microsoft.com/winfx/2006/x…...
三相交错LLC软启动控制程序算法实现---充电桩电源设计实战细节
简介 充电桩充电终端是一款单枪最大功率达到600kW的充电桩。它具有以下特点: 充电枪线长3.5米,重量小于90kg,额定电压1000V,最大电流600A,最大功率600kW。 高宽深为1700340295mm。 该充电桩采用模块化设计,具有较高的可靠性和可维护性。 充电时间大约在30分钟左右,…...

Chrome 115之后的版本,安装和使用chromedriver
在Python中使用selenium 时报如下错误: 1. 老版本chrome对应的chromedriver 下载地址:CNPM Binaries Mirror 2. 新版本chrome对应的chromedriver 下载地址:Chrome for Testing availability...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...