RTT学习之线程
获得线程:rt_thread_t rt_thread_self(void);
一 线程的创建和删除:
rt_thread_create()创建的句柄,对应的删除rt_thread_delete(),注意线程的删除只是将线程的状态该为close,进入空闲任务才删除。
rt_thread_init()函数对应的是rt_thread_detach()
二 线程的就绪和挂起:RTT只能是讲一个已经就绪的线程挂起,而不能对已经挂起(调用系统延时函数)的任务再执行挂起操作用suspend!
rt_thread_startup(taskn):使当前线程就绪;
rt_err_t rt_thread_suspend (rt_thread_t thread)使当前线程挂起但很少用,除非在调用该函数后立刻调用rt_schedule()进行调度;
对应的恢复就绪rt_err_t rt_thread_resume (rt_thread_t thread)后也紧跟调用rt_schedule();
yield主动切出挂起;rt_thread_yield()函数和rt_schedule()函数的区别:前者从当前线程中切出,插入到本优先级列表尾端,然后转到同优先级的其它线程执行;而后者当前线程不一定切出,只是从调度器重新检查一遍最高优先级就绪任务并执行;
三线程的休眠:
rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);
四线程控制:rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);使之就绪、删除、或更改优先级
五空闲线程:
void rt_thread_idle_init(void);
void rt_thread_idle_sethook(void (*hook)(void));
rt_err_t rt_thread_idle_delhook(void (*hook)(void));设置的钩子函数必须保证空闲线程在任何时刻都不会处于挂起状态,主要用于设置状态指示(因不能调用系统延时函数,等待信号所以用处不大,最多只能用条件判断的指示灯)。低功耗模式。删除的线程资源回收。
void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to)调度器钩子用以确定在某个时刻发生了什么线程切换。 六 线程设计:
1 需要知道什么时候让线程进入非就绪态,如果一直就绪,低优先级线程就可能得不到执行的机会。
2 需要确定线程的运行周期、运行时间(task1的响应时间(周期)有要求,则要求其它高优先级任务taskn的执行时间不能超过task1的周期)、优先级的因素
3线程创建步骤:
3.0系统启动流程架构:在rt_application_init()中创建main线程($super$$main必须成对使用,这里是让扩展了Main之后返回到用户main,然后删除自己。硬件初始化,系统初始化,
RT-Thread通过扩展main函数的方式都在component.c里面实现,所以在主main中只有用户自己创建的线程。main线程执行到最后,通过LR寄存器指定的链接地址退出,在
创建main线程的时候,线程栈对应LR寄存器的内容是rt_thread_exit()函数,在
rt_thread_exit里面会把main线程占用的内存空间都释放掉

3.1 创建线程函数,执行什么功能;定义线程堆栈和线程控制块(ID:)
3.2用rt_thread_init()初始化线程任务,任务进入初始化态,调用rt_thread_startup(&led1_thread); 后参与线程调度
#define LED1_StackSize 1024
static rt_uint8_t rt_led1_thread_stack[LED1_StackSize];
static struct rt_thread led1_thread;
rt_thread_init(&led1_thread, /* 线程控制块 */ (1)
"led1", /* 线程名字 */ (2)
led1_thread_entry, /* 线程入口函数 */ (3)
RT_NULL, /* 线程入口函数参数 */ (4)
&rt_led1_thread_stack[0], /* 线程栈起始地址 */ (5)
sizeof(rt_led1_thread_stack), /* 线程栈大小 */ (6)
3, /* 线程的优先级 */ (7)
20); /* 线程时间片,相同优先级才起作用,对只有一个线程时那么该参数不起作用 */
,
线程的栈、控制块用的若静态内存(由编译器负责分配),必须由用户手动预先定义,但这种方法我们在使用RT-Thread的时候用的比较少,通常的方法是在线程创建的时候动态
的分配线程栈和线程控制块的内存空间,即推荐使用动态法创建线程(堆栈大小、优先级、时间片最好宏定义给出增加灵活性)。接下来我们讲解下“创建单线程—SRAM动态内存”的方法(堆),在board.c

static rt_thread_t led1_thread = RT_NULL;
led1_thread = /* 线程控制块指针 */ (1)
rt_thread_create( "led1", /* 线程名字 */ (2)
led1_thread_entry, /* 线程入口函数 */ (3)
512, /* 线程栈大小 不用指定起始地址*/ (5)
3, /* 线程的优先级 */ (6)
20); /* 线程时间片 */ (7)
RT_NULL, /* 线程入口函数参数 */ (4)
if (led1_thread != RT_NULL)
rt_thread_startup(led1_thread); /* 启动线程,开启调度 */
else
return -1;
线程的管理:
RT-Thread内核中采用了基于位图的优先级算法(时间复杂度O(1),即与就绪线程的多少无关)。
在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身。
时间片轮转调度仅在当前系统中无更高优先级就绪线程存在的情况下才有效,也可以是一个任务的2个副本。
RTT学习之线程的更多相关文章
- rtt学习之线程间同步与通信
一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...
- python自动化开发学习 进程, 线程, 协程
python自动化开发学习 进程, 线程, 协程 前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...
- ORB-SLAM2 论文&代码学习 —— LocalMapping 线程
转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12360913.html 本文要点: ORB-SLAM2 Local ...
- 手写一个线程池,带你学习ThreadPoolExecutor线程池实现原理
摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥 ...
- 学习C#线程
2016-12-17 无意间看到了关于C#线程的讲解.经过一下午的学习后,慢慢的对线程也有了一定的理解.这里讲解的是最基础的内容,包括线程的创建.睡眠.等待.终止. 实验环境:Visual studi ...
- java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService
前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...
- java SE学习之线程同步(详细介绍)
java程序中可以允许存在多个线程,但在处理多线程问题时,必须注意这样一个问题: 当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量时,那么这个 ...
- 从使用到原理学习Java线程池
线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所 ...
- Qt学习:线程间共享数据(使用信号槽传递数据,必须提前使用qRegisterMetaType来注册参数的类型)
Qt线程间共享数据主要有两种方式: 使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的: 使用singal/slot机制,把数据 ...
随机推荐
- 【转】基于OCS实现高速缓存
OCS简介 OCS( Open Cache Service)为分布式高速缓存服务,主要实现热点数据的快速响应: OCS支持Key/Value的数据结构,兼容memcachebinary protoco ...
- 使用sphinx快速生成Python API 文档
一 简单介绍 不管是开源还是闭源,文档都是很重要的.当然理论上说,最好的文档就是代码本身,但是要让所有人都能读懂你的代码这太难了.所以我们要写文档.大部分情况,我们不希望维护一份代码再加上一份文档, ...
- linux 定制
转载至http://luyafei.blog.51cto.com/1092421/1131532 测试环境: VMware Workstation 8.0 CentOS 6.7 x86_64 1.安装 ...
- VS2015无法创建C++工程解决方法!!
VS2015默认安装时候没有安装C++,如果安装C++没有选择全部C++项目,则无法创建C++工程,在控制面板里的删除程序中,选择VS2015,随后选择修改,把C++项目都选择上就可以了,这样安装完毕 ...
- day03-Linux操作系统目录结构
一. Linux系统目录表示 ‘/’表示根目录: ‘.’表示当前目录 ...
- winform按钮文字换行
用button的Bounds属性 btn.Bounds = new Rectangle(new Point(5 + i * 143, 25), new Size(100, 60));
- phaser小游戏框架学习(一)
这两天由于项目的需要,所以简单学了一下phaser框架. 官网:http://phaser.io/ 还有一个phaser小站,是中文的网站,但是内容不如英文文档全,大家也可以去看这个网站,需要查阅AP ...
- Reincarnation HDU - 4622
\(\color{#0066ff}{ 题目描述 }\) 给定一个字符串,多次询问某一字串的f值 f(s)代表s的不同字串数量 \(\color{#0066ff}{输入格式}\) 第一行T,代表数据组数 ...
- linux线程切换和进程切换
进程切换分两步: 1.切换页目录以使用新的地址空间 2.切换内核栈和硬件上下文 对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的. ...
- mongoDB副本集+分片集群
首先搭建一个副本集(三台机器) 主,从,仲裁 然后搭建分片shard1,在每台机子上启用shard1(这里就写一个分片吧!!如果写多了怕初学者会混乱,先写一个.然后可以按照同样的方法写第二个,第三个) ...