RT-Thread学习笔记(3)- 线程的创建与删除

(一)RTT的线程

RTT的线程相当于别的RTOS的任务,它的组成有三部分:

1、线程代码:类似我们以前在写裸机代码的时候,实现某个功能的函数,在这个地方实现我们的功能逻辑。

2、线程控制块:是一个结构体,每一个线程都有属于自己的结构体,方便RTT来管理,实现诸如任务调度、启动、删除等操作。

3、堆栈:保存对应线程的环境,方便重新获取CPU使用权时恢复离开时的状态。

(二)动态线程与静态线程

静态线程与动态线程的区别在于堆栈,动态线程的堆栈是动态分配的,而静态线程的堆栈是预先就分配好的(通常是定义一个全局数组)。

至于为什么要区分?原因在于两者的堆栈存储的位置不一样,我们选择静态或动态线程是至于空间和速度考虑。当然对于STM32这种单片机,几乎没啥区别。(分析,具体补一篇)

(三)具体举例:线程的创建与删除

还是先看主函数,简单到恐怖如斯:

extern int thread_sample_init(void);

//第三次课 2018.7.24
#include <rtthread.h>

int main(void)
{
    /* user app entry */  
    thread_sample_init();
    return 0;
}

看看thread_sample_init()这个函数,它创建了两个线程,具体分析,已经在注释解释的很清楚了。

/* 线程示例的初始化 */
int thread_sample_init(void)
{
    /* 创建线程1 */
    tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
                            thread1_entry, RT_NULL,   /* 入口是thread1_entry,参数是RT_NULL */
                            THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);//优先级为 25
    if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
    {
        tid1->cleanup = thread1_cleanup;/*thread1_cleanup在线程1退出后执行*/
        rt_thread_startup(tid1);
    }
    /* 创建线程2 */
    tid2 = rt_thread_create("t2", /* 线程2的名称是t2 */
                            thread2_entry, RT_NULL,   /* 入口是thread2_entry,参数是RT_NULL */
                            THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
    {
        tid2->cleanup = thread2_cleanup;
        rt_thread_startup(tid2);
    }
    return 0;
}

接着,我们看看线程1和线程2的实体,分别为thread1_entry()和thread2_entry(),线程1的优先级为25,而线程2的优先级为24(数字越小,优先级越高)。线程1是不断打印count字符的大小,而线程2则是延时一段时间后,删除线程1,再延时一段时间后退出。而thread1_cleanup和thread2_cleanup在对应线程退出后执行。

代码注释详细,不懂请留言。

/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{
    rt_uint32_t count = 0;

    while (1)
    {
        /* 线程1采用低优先级运行,一直打印计数值 */
        rt_kprintf("thread count: %d\n", count ++);
        count ++;
    }
}

static void thread1_cleanup(struct rt_thread *tid) //当线程退出的时候执行
{
    if (tid != tid1)
    {
        return ;
    }
    rt_kprintf("thread1 end\n");
    tid1 = RT_NULL;
}

/* 线程2的入口函数 */
static void thread2_entry(void *parameter)
{
    /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */

    /* 线程2启动后先睡眠10个OS Tick */
    rt_thread_delay(10);

    /*
     * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程
     * 队列
     */
    rt_thread_delete(tid1);

    /*
     * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程
     * idle线程将执行真正的线程1控制块和线程栈的删除
     */
    rt_thread_delay(10);
}

static void thread2_cleanup(struct rt_thread *tid)
{
    /*
     * 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
     * 程中释放)
     */

    if (tid != tid2)
    {
        return ;
    }
    rt_kprintf("thread2 end\n");
    tid2 = RT_NULL;
}

实验效果如下,由现象可以,达到预期要求。

(四)总结

由于时间有限,很多东西都没有深究,比如也没有写关于静态线程的代码实现。这些坑慢慢补,个人还是觉得还是要多使用RTT来实现一些具体的项目,遇到问题后,努力解决后,能更加理解这个操作系统。

总结一下,用到的函数:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值