zoukankan      html  css  js  c++  java
  • 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=0; rt_hw_led_init(); while (1) {   if (++count>=4) count = 0;   rt_hw_led_on(ledTable[count][0]);   rt_hw_led_off(ledTable[count][1]);   rt_hw_led_off(ledTable[count][2]);   rt_hw_led_off(ledTable[count][3]);   rt_thread_delay( RT_TICK_PER_SECOND/2 );   /* 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[512];
    /* 静态线程的 线程控制块 */
    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[0],
                  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,                       
    512,
                           21,
                           2);   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[512];
    
    /* 静态线程的 线程控制块 */
    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[0], 
                          sizeof(led1_stack), 
                                          20, //优先级 20 ,
                                           2);//时间片 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,
                                          512, 
                                           21, 
                                           2);
    
        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 的使用权。

  • 相关阅读:
    整理了一份FAQ,新手看一下
    分享:pythonbitstring 3.1.2 发布
    分享:TokuDB v7 发布,并宣布全面开源
    在美国学CS能挣多少钱?美国IT公司标准 offer package详细数字及绿卡政策 | 美国留学申请与就业找工作咨询博客|Warald|一亩三分地论坛
    写的split带改进
    分享:一个多进程并发执行程序ps命令 ls命令
    分享:vi/vim使用进阶: 指随意动,移动如飞 (一)
    waning rm i rm rvfi
    分享:C++中头文件、源文件之间的区别与联系
    分享:神奇的动归状态转移方程——最优子序列
  • 原文地址:https://www.cnblogs.com/yygsj/p/5498793.html
Copyright © 2011-2022 走看看