rt_thread线程管理

Posted 旭日初扬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rt_thread线程管理相关的知识,希望对你有一定的参考价值。

一、概述

  • RT-Thread 的线程可认为是一系列独立线程的集合。
  • 每个线程在 自己的环境中运行。在任何时刻,只有一个线程得到运行,RT-Thread 调度器决定运行哪个线程。
  • 每个 RT-Thread 线程都有自己的堆栈。
  • RT-Thread 的线程模块可以给用户提供多个线程,实现了线程之间的切换和通信,帮助用户管理业务程序流程。
  • RT-Thread 中的线程是抢占式调度机制,同时支持时间片轮转调度方式。
  • 高优先级的线程可打断低优先级线程,低优先级线程必须在高优先级线程阻 塞或结束后才能得到调度。
  • RT-Thread 中提供的线程调度器是基于优先级的全抢占式调度:在系统中除 了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外, 系统的其他部分都是可以抢占的,包括线程调度器自身。
  • RT-Thread 中提供的线程调度器是基于优先级的全抢占式调度:在系统中除 了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外, 系统的其他部分都是可以抢占的,包括线程调度器自身。
  • rt_thread的实时性:当所有就绪线程都链接在它们对应的优先级队列中时,抉择过程就将演变为在优先级数组中寻找具有最高优先级线程的非空链表。RT-Thread 内核中采用了基于位图的优先级算法(时间复杂度O(1),即与就绪线程的多少无关),通过位图的定位快速的获得优先级最高的线程。
  • RT-Thread 内核中也允许创建相同优先级的线程。相同优先级的线程采用时 间片轮转方式进行调度(也就是通常说的分时调度器),时间片轮转调度仅在当前系统中无更高优先级就绪线程存在的情况下才有效。
  • 线程调度的原则是一旦线程状态发生了改变,并且当前运行 的线程优先级小于优先级队列组中线程最高优先级时,立刻进行线程切换(除非 当前系统处于中断处理程序中或禁止线程切换的状态)。
  • 因为 RT-Thread 调度器 的实现是采用优先级链表的方式,所以系统中的总线程数不受限制,只和系统所 能提供的内存资源相关。为了保证系统的实时性,系统尽最大可能地保证高优先 级的线程得以运行。

二、线程的状态

1、初始态(RT_THREAD_INIT)

创建线程的时候,将线程的状态设定为初始态。

2、就绪态(RT_THREAD_READY)

此线程在就绪列表中,具备执行的能力,等待cpu

3、运行态(RT_THREAD_RUNNING)

此线程正在运行,占用处理器。

4、挂起态(RT_THREAD_SUSPEND)

此线程正在等待某个时序或者外部中断,改线不在就绪列表中,包含线程被 挂起、线程被延时、线程正在等待信号量、读写队列或者等待读写事件等。

5、关闭态(RT_THREAD_CLOSE)

该线程运行结束,等待系统回收资源。

三、线程状态切换实例

#include "board.h"
#include "rtthread.h"


/* 定义线程控制块 */
static rt_thread_t led1_thread = RT_NULL;
/* 线程主体函数 */
static void led1_thread_entry(void* parameter);

/* 定义线程控制块 */
static rt_thread_t key_thread = RT_NULL;
/* 线程主体函数 */
static void key_thread_entry(void* parameter);

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()

	rt_kprintf("线程管理程实验!\\r\\n");
	rt_kprintf("按下KEY_UP挂起LED线程,按下KEY1恢复LED线程!\\r\\n");
	
	//创建LED1线程
	led1_thread =rt_thread_create( 
					"led1",              /* 线程名字 */
                     led1_thread_entry,   /* 线程入口函数 */
                     RT_NULL,             /* 线程入口函数参数 */
                     512,                 /* 线程栈大小 */
                     3,                   /* 线程的优先级 */
                     20);                 /* 线程时间片 */
	
	/* 启动线程,开启调度 */
    if(led1_thread != RT_NULL)
		rt_thread_startup(led1_thread);
    else
		return -1;
	
	//创建KEY线程
	key_thread =rt_thread_create( 
					"key",              /* 线程名字 */
                     key_thread_entry,   /* 线程入口函数 */
                     RT_NULL,             /* 线程入口函数参数 */
                     512,                 /* 线程栈大小 */
                     2,                   /* 线程的优先级 */
                     20);                 /* 线程时间片 */
	
	/* 启动线程,开启调度 */
    if(key_thread != RT_NULL)
		rt_thread_startup(key_thread);
    else
		return -1;
	


//LED1线程
static void led1_thread_entry(void* parameter)
	
    while(1)
    
        LED1=0;
        rt_thread_delay(200);   /* 延时200个tick */
		rt_kprintf("led1_thread running,LED1_ON\\r\\n");
		LED1=1;     
        rt_thread_delay(500);   /* 延时500个tick */
		rt_kprintf("led1_thread running,LED1_OFF\\r\\n");
    


//KEY线程
static void key_thread_entry(void* parameter)

	u8 key=0;
	rt_err_t erflag=0;
	
	while(1)
	
		key=KEY_Scan(0);
		if(key==KEY_UP_PRESS)
		
			rt_kprintf("LED1线程挂起!\\r\\n");
			erflag=rt_thread_suspend(led1_thread);
			if(erflag==RT_EOK)
				rt_kprintf("线程挂起成功!\\r\\n");
			else
				rt_kprintf("线程挂起失败!\\r\\n");
		
		else if(key==KEY1_PRESS)
		
			rt_kprintf("LED1线程恢复!\\r\\n");
			erflag=rt_thread_resume(led1_thread);
			if(erflag==RT_EOK)
				rt_kprintf("线程恢复成功!\\r\\n");
			else
				rt_kprintf("线程恢复失败!\\r\\n");
		
		rt_thread_delay(20);   /* 延时20个tick */
	

以上是关于rt_thread线程管理的主要内容,如果未能解决你的问题,请参考以下文章

创建rt_thread线程

创建rt_thread线程

rt_thread的消息队列

rt_thread线程间通讯

rt_thread的消息队列

RT_THREAD之工具学习