RT-Thread创建静态、动态线程
RT-Thread 实时操作系统核心是一个高效的硬实时核心,它具备非常优异的实时性、稳
定性、可剪裁性,当进行最小配置时,内核体积可以到 3k ROM 占用、 1k RAM 占用。
RT-Thread 中的“线程”一般由三部分组成:线程代码(函数)、 线程控制块、 线程堆栈。
/* 指向线程控制块的指针*/
static struct rt_thread led_thread= RT_NULL; void led_thread_entry(void* parameter)
{
rt_uint8_t count=;
rt_hw_led_init();
while ()
{
if (++count>=) count = ;
rt_hw_led_on(ledTable[count][]);
rt_hw_led_off(ledTable[count][]);
rt_hw_led_off(ledTable[count][]);
rt_hw_led_off(ledTable[count][]);
rt_thread_delay( RT_TICK_PER_SECOND/ );
/* sleep 0.5 second and switch to other thread */
}
}
上面即是一个典型的线程代码结构—无限死循环,当然还有一种线程结构是顺序执行的,比如初始化线程,它执行到 return(),就会返回,当其返回后,系统会在 idle 线程中将其删除,从而使其退出调度队列。一般情况下用户线程都将是一个无限循环结构。
线程堆栈:
static rt_uint8_t led_stack[ 512];
线程堆栈是一段连续的内存块,当线程切换后,为了满足线程切换和响应中断时保存cpu 寄存器中的内容及任务调用其它函数时的准备,每个线程都要配有自己的堆栈.
创建一个我们自己的线程
前面说了这么多,我们还是来自己建立一个线程,这样的话印象更深刻。
RT-Thread 中的线程分为静态线程—线程堆栈由编译器静态分配,使用 rt_thread_init ()
函数创建和动态线程—线程堆栈由系统动态分配,使用 rt_thread_create()函数创建。/* 静态线程的 线程堆栈*/
static rt_uint8_t led1_stack[];
/* 静态线程的 线程控制块 */
static struct rt_thread led1_thread;
void demo_thread_creat(void)
{
rt_err_t result;
/* 动态线程的 线程控制块指针 */
rt_thread_t led2_thread;
rt_hw_led_init();
/* 创建静态线程 : 优先级 20 ,时间片 2 个系统滴答 */
result = rt_thread_init( &led1_thread,
"led1",
static_thread_entry,
RT_NULL,
(rt_uint8_t*)&led1_stack[],
sizeof(led1_stack),
20,
2);
if (result == RT_EOK)
{
rt_thread_startup(&led1_thread);
}
/* 创建动态线程 : 堆栈大小 512 bytes ,优先级 21 ,时间片 2 个系统滴答 */
led2_thread = rt_thread_create("led2",
dynamic_thread_entry,
RT_NULL,
,
21,
);
if (led2_thread != RT_NULL)
rt_thread_startup(led2_thread);
}
静态线程 VS 动态线程
从上例可看出,静态、动态线程在做同样的事情时,从效果上看,是没有任何差别的!
那么,我们在实际中如何抉择?使用静态线程时,必须先定义静态的线程控制块,并且定义好堆栈空间,然后调用rt_thread_init() 来完成线程的初始化工作。采用这种方式,线程控制块和堆栈占用的内存会放在 RW/ZI 段,这段空间在编译时就已经确定,它不是可以动态分配的,所以不能被释放,而只能使用 rt_thread_detach() 函数将该线程控制块从对象管理器中脱离。使用动态定义方式 rt_thread_create() 时, RT-Thread 会动态申请线程控制块和堆栈空间。在编译时, 编译器是不会感知到这段空间的,只有在程序运行时, RT-Thread 才会从系统堆中申请分配这段内存空间,当不需要使用该线程时,调用 rt_thread_delete() 函数就会将这段申请的内存空间重新释放到内存堆中。这两种方式各有利弊,静态定义方式会占用 RW/ZI 空间,但是不需要动态分配内存,运行时效率较高,实时性较好。 动态方式不会占用额外的 RW/ZI 空间,占用空间小,但是
运行时需要动态分配内存,效率没有静态方式高。 总的来说,这两种方式就是空间和时间效率的平衡,可以根据实际环境需求选择采用具体的分配方式。
static void rt_hw_led_init(void);
static void static_thread_entry(void* parameter);
static void dynamic_thread_entry(void* parameter); /* 变量分配4字节对齐 */
ALIGN(RT_ALIGN_SIZE) /* 静态线程的 线程堆栈*/
static rt_uint8_t led1_stack[]; /* 静态线程的 线程控制块 */
static struct rt_thread led1_thread; void demo_thread_creat(void)
{
rt_err_t result;
/* 动态线程的 线程控制块指针 */
rt_thread_t led2_thread; rt_hw_led_init(); /* 创建静态线程 : */
result = rt_thread_init(&led1_thread,
"led1",
static_thread_entry,
RT_NULL,
(rt_uint8_t*)&led1_stack[],
sizeof(led1_stack),
, //优先级 20 ,
);//时间片 2个系统滴答
if (result == RT_EOK)
{
rt_thread_startup(&led1_thread);
} /* 创建动态线程 : 堆栈大小512 bytes ,优先级 21 ,时间片 2个系统滴答 */
led2_thread = rt_thread_create("led2",
dynamic_thread_entry,
RT_NULL,
,
,
); if (led2_thread != RT_NULL)
rt_thread_startup(led2_thread); /*上面代码中的 20、 8 既是线程的优先级, 5 是为线程所分配的时间片。这里需要注意的
是, 当一个线程的优先级独一无二的时候,它的时间片这个参数将失去作用,我们不要认为
上面的两个线程运行完 5 个系统 ticks 后就会主动交出 cpu 使用权,当运行完 5 个 ticks
后如果它不需等待任何资源,也不主动让出 cpu 使用权的话,它还会继续运行,时间片这个
参数只在具有相同优先级的线程之间起作用,可是即便如此,这个参数也不能设为 0,因为
你不知道后续是否还会创建线程。*/ }
由于我们的线程一般都是一个无限循环,而 RT-Thread 又是一个抢占式的内核,所以为了使高优先级的线程不至于独占 CPU,可以给其他优先级较低的线程获得CPU使用权的机会,我们往往需要在线程中的合适位置调用系统函数 rt_thread_delay(),使当前线程的运行延时一段时间并进行一次任务调度,以让出 CPU 的使用权。
RT-Thread创建静态、动态线程的更多相关文章
- RT-thread线程创建:动态线程与静态线程
本文介绍了如何创建一个动态线程和一个静态线程 RT-thread版本:RT-thread system 3.1.0 开发环境:MDK5 为了编程方便,创建了sample1.c文件,然后添加到工程中 话 ...
- C/C++ Muti-Thread多线程编程学习(之)线程Thread | 创建、运行、结束
文章目录 前言 线程 Thread 创建线程 CreateThread _beginthread _beginthreadex pthread_create 线程运行 结束线程 前言 多线程(Mu ...
- Linux命令之ar - 创建静态库.a文件和动态库.so
转自:http://blog.csdn.net/eastonwoo/article/details/8241693 用途说明 创建静态库.a文件.用C/C++开发程序时经常用到,但我很少单独在命令行中 ...
- 在Linux中创建静态库.a和动态库.so
转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...
- Xcode 创建静态库和动态库
1.linux中静态库和动态库区别: 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 静态库:这类库的名字一般是libxxx.a:利用静态函数库编译成的文件 ...
- 使用Thread类可以创建和控制线程
1.创建线程 static void Main(string[] args) { /* Thread类 * 创建控制线程 * 其构造函数接受ThreadStart和ParameterizedThrea ...
- 在Linux中创建静态库和动态库
我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库. 动态库在程序编译时并不会被连接到目标代码中 ...
- linux中创建静态库和动态库
1. 函数库有两种:静态库和动态库. 静态库在程序编译的时候会被连接到目标代码中,程序运行时将不再需要改静态库. 动态库中程序编译的时候并不会连接到目标代码中,而是在程序运行时才被载入,因此在程序运行 ...
- [非技术参考]C#基础:使用Thread创建线程(1)
Thread类可以创建和控制线程,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数.下面我们用一个例子来解释怎样用Thread类 ...
随机推荐
- hdu 2795 线段树(纵向)
注意h的范围和n的范围,纵向建立线段树 题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子思路:每次找到最大值的位子,然后减去L线段树功能:query:区间求最大值的位子(直接 ...
- Struts2拦截器原理以及实例
一.Struts2拦截器定义 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. ...
- java.lang.NoClassDefFoundError: org/apache/avro/ipc/Responder
文章发自:http://www.cnblogs.com/hark0623/p/4170174.html 转发请注明 java.lang.NoClassDefFoundError: org/a ...
- throws 和 throw
package unit5; public class Person { private int age; private String name; public String getName() { ...
- Spring的属性编辑器
bean类 import java.util.Date; public class Bean { private Date date; public Date getDate() { return d ...
- SU sugabor命令学习
不足之处,欢迎批评指正.
- QUnit使用笔记-5简化编写
在测试中,如果用到了大量相同的方法返回判断结果,可以将他们简化; 使用push(): push( result/*boolean,result of assert*/, actual, /*objec ...
- NGUI全面实践教程(大学霸内部资料)
NGUI全面实践教程(大学霸内部资料) 试读文档下载地址:链接:http://pan.baidu.com/s/1jGosC9g 密码:8jq5 介绍:NGUI全面实践教程(大学霸内部资料)本书是国 ...
- 构造 hihocoder 1257 Snake Carpet (15北京I)
题目传送门 题意:贪吃蛇,要求长度奇数的蛇转弯次数为正奇数,长度偶数转弯次数为正偶数,且组成矩形.(北大出的题咋都和矩形相关!!!) 分析:构造找规律,想到就简单了.可以构造 宽:(n + 1) / ...
- DFS(剪枝) POJ 1724 ROADS
题目传送门 题意:问从1到n的最短路径,同时满足花费总值小于等于k 分析:深搜+剪枝,如果之前走过该点或者此时的路劲长度大于最小值就不进行搜索. /************************** ...