当前位置:   article > 正文

玩转RT-Thread系列教程(1)--线程的使用_rt-thread教程

rt-thread教程

玩转RT-Thread系列教程(1)–线程的使用

一、什么是线程

我们或许都听说过多线程的概念,其实在多CUP处理器上才真正的存在多线程的概念,每个CPU同时运行处理多个不同的任务。

那在我们的单核CPU的单片机上如何使用“多线程”来处理同一时刻请求的不同任务,来做到”同时“进行呢?

这个时候就需要引入线程管理了。在多线程操作系统中,需要开发人员把一个复杂的应用分解成多个小的、可调度的、

序列化的程序单元。而在 RT-Thread 中,与上述子任务对应的程序实体就是线程。

RT-Thread 的线程调度器是抢占式的,主要的工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,

最高优先级的任务一旦就绪,总能得到 CPU 的使用权。

来源RT-Thread文档中心

二、线程的分类

线程分为五种状态:初始------->就绪------>运行------>挂起------>关闭

空闲线程:优先级最低,永远为就绪态,不被挂起。 用处:回收被删除线程资源(回收僵尸线程)

当线程优先级相同时,采用时间片轮转方式调度,单位一个时钟节拍

比如:A:10,B:5,那么A线程执行10个节拍,B线程执行5个节拍


rt_thread_yield():当前线程被换出,相同优先级的下一个就绪线程将被执行。

rt_schedule():当前线程并不一定被换出,而是在系统中选取就绪的优先级最高的线程执行。


三、线程的创建

创建线程分为两种方式:1、动态创建线程 2、静态创建线程

两种方式各有优缺点,使用分具体场合。接下来我将具体分析以下两种创建线程方式。

1.创建线程(静态)

占用RAM空间(RW/ZI 空间),用户分配栈空间和线程句柄

优点:运行时不需要动态分配内存,运行时效率较高,实时性较好,

缺点:内存不能被释放,只能使用 rt_thread_detach() 函数将该线程控制块从对象管理器中脱离。

static rt_uint8_t thread1_stack[512];   //线程栈
static struct rt_thread thread1;		//线程控制块
rt_thread_init(&thread1,				//线程handle
               "thread1",				//线程名称
               thread1_entry,			//线程入口函数
               RT_NULL,					//线程入口参数
               &thread1_stack[0],       //线程栈地址
               sizeof(thread1_stack),	//线程栈大小
               15, 	 					//线程优先级
               5);			 			//线程时间片
rt_thread_startup(&thread1);			//线程进入就绪态
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.创建线程(动态)

依赖与内存堆管理器,系统自动从动态内存堆分配栈空间

优点:创建方便,参数比较静态简便,内存可以由用户释放,调用 rt_thread_delete() 函数就会将这段申请的内存空间重新释放到内存堆中。

缺点:运行时需要动态分配内存,效率没有静态方式高,

static rt_thread_t thread_id = RT_NULL;
thread_id = rt_thread_create("dynamic_th",    //名称
                              dynamic_entry,  //线程代码
                              RT_NULL,        //参数
                              1024,           //栈大小
                              15,             //优先级
                              20);            //时间片
if (thread_id != RT_NULL)
   rt_thread_startup(thread_id);			  //线程进入就绪态
else
   rt_kprintf("dynamic_thread create failure\n");
return RT_EOK;                                                          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

四、创建线程示例

使用动态+静态方式,创建两个线程

//动态线程任务
static void dynamic_entry(void *param)
{
		static int cnt = 0;
	
    while (++cnt)
    {
		rt_kprintf("dynamic_thread is run:%d\n",cnt);
        rt_thread_mdelay(500);
    }
}

//静态线程任务
static void static_entry(void *param)
{
		static int cnt = 0;
	
    while (++cnt)
    {
		rt_kprintf("static_thread is run:%d\n",cnt);
        rt_thread_mdelay(500);
    }
}

static rt_uint8_t thread1_stack[512];   		  //线程栈
static struct rt_thread static_thread;			  //线程控制块
int thread_sample(void)
{
    static rt_thread_t thread_id = RT_NULL;
    thread_id = rt_thread_create("dynamic_th",    //名称
                                 dynamic_entry,   //线程代码
                                 RT_NULL,         //参数
                                 1024,            //栈大小
                                 15,              //优先级
                                 20);             //时间片

    if (thread_id != RT_NULL)
        rt_thread_startup(thread_id);			  //线程进入就绪态
    else
        rt_kprintf("dynamic_thread create failure\n");

		rt_thread_init(&static_thread,							//线程handle
									 "static_thread",			//线程名称
									 static_entry,				//线程入口函数
									 RT_NULL,					//线程入口参数
									 &thread1_stack[0],       	//线程栈地址
									 sizeof(thread1_stack),	  	//线程栈大小
									 15, 	 					//线程优先级							    		
									 5);						//线程时间片		 							  		
		rt_thread_startup(&static_thread);						//线程进入就绪态		
									 
    return RT_EOK;									 
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_sample, thread sample);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
编译、下载

打开串口调试助手,输入thread_sample命令,可以看出我们的两个线程以及创建并且正常运行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/67375
推荐阅读
相关标签
  

闽ICP备14008679号