欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RT-Thread线程

程序员文章站 2022-07-11 18:52:43
...

线程

RT-Thread中,线程由三部分组成:线程代码(入口函数)、线程控制块线程堆栈

线程代码

线程代码有两种结构:无限循环结构和顺序执行结构。

//无限循环结构
void thread_entry(void *parameter)
{
    while(1)
    {
        /*等待事件的发生*/
        //........
        /*处理事件*/
    }
}

//顺序执行结构
void thread_entry(void *parameter)
{
	/*事务1处理*/
    /*事务2处理*/
	//........
	/*事务N处理*/
}

线程栈

RT-Thread每个线程都具有独立的栈空间,当进行线程切换时,系统会将当前线程的上下文保存在线程栈中,当线程要恢复运行时,再从线程栈中读取上下文信息,恢复线程的运行。

线程上下文是指线程执行时的环境,具体来说就是各个变量和数据包括所有寄存器变量、堆栈信息、内存信息等。

线程栈在形式上是一段连续的内存空间,可以通过定义一个数组或者申请一段动态内存来作为线程的栈。

创建线程

创建静态线程

rt_err_t rt_thread_init(struct thread *thread,	//线程控制块指针
               const char *name,	//线程名
               void(*entry)(void *parameter),	//入口函数
               void *parameter,		//参数(一般为RT_NULL)
               void *stack start,	//线程内存块起始地址
               rt_unit32_t stack_size,	//线程内存块大小
               rt_uint8_t priority,	//线程优先级
               rt_uint32_t tick);	//时间片

创建动态线程

rt_thread_t rt_thread_create(const char *name,	//线程名
               void(*entry)(void *parameter),	//入口函数
               void *parameter,		//参数(一般为RT_NULL)
               rt_unit32_t stack_size,	//线程内存块大小
               rt_uint8_t priority,	//线程优先级
               rt_uint32_t tick);	//时间片

创建线程后启动线程用**rt_thread_startup()**函数

rt_err_t rt_thread_startup(rt_thread_t thread)

调用此函数后,创建的线程会被加入到线程的就绪队列,执行调度。

线程创建举例

/*
 * 程序清单:创建/删除、初始化线程
 *
 * 这个例子会创建两个线程,一个动态线程,一个静态线程。
 * 一个线程在运行完毕后自动被系统删除,另一个线程一直打印计数。
 */
#include <rtthread.h>

#define THREAD_PRIORITY         25	//优先级
#define THREAD_STACK_SIZE       512	//栈空间大小
#define THREAD_TIMESLICE        5	//时间片

/*tid1为线程控制块的指针*/
static rt_thread_t tid1 = RT_NULL;

/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{
    rt_uint32_t count = 0;
	//无限循环结构
    while (1)
    {
        /* 线程1采用低优先级运行,一直打印计数值 */
        rt_kprintf("thread1 count: %d\n", count ++);
        rt_thread_mdelay(500);
    }
}

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];

static struct rt_thread thread2;

/* 线程2入口 */
static void thread2_entry(void *param)
{
    rt_uint32_t count = 0;

    /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */
    for (count = 0; count < 10 ; count++)
    {
        /* 线程2打印计数值 */
        rt_kprintf("thread2 count: %d\n", count);
    }
    rt_kprintf("thread2 exit\n");
    /* 线程2运行结束后也将自动被系统删除
    (线程控制块和线程栈依然在idle线程中释放) */
}

/* 删除线程示例的初始化 */
int thread_sample(void)
{
    /* 创建线程1,名称是thread1,入口是thread1_entry*/
	/*动态线程*/
	tid1 = rt_thread_create("thread1",	//线程名
                            thread1_entry, RT_NULL,	//入口函数及参数(RT_NULL)
                            THREAD_STACK_SIZE,	//线程栈大小
                            THREAD_PRIORITY, THREAD_TIMESLICE);	//线程优先级及时间片
    
    /* 如果获得线程控制块,启动这个线程 */
	if (tid1 != RT_NULL)	//创建成功,则tid1非零,即不为RT_NULL
        rt_thread_startup(tid1);	//启动线程tid1
    

    /* 初始化线程2,名称是thread2,入口是thread2_entry */
	/*静态线程*/
    rt_thread_init(&thread2,	//线程控制块指针
                   "thread2",	//线程名
                   thread2_entry,	//入口函数
                   RT_NULL,	//参数
                   &thread2_stack[0],	//线程内存块起始地址
                   sizeof(thread2_stack),	//线程栈大小
                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);	//线程优先级及时间片
    rt_thread_startup(&thread2);

    return 0;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_sample, thread sample);