| (一)状态
 
 
 
 | 线程通过调用函数 rt_thread_create/init() 进入到 | 初始状态(RT_THREAD_INIT) |  | 初始状态的线程通过调用函数 rt_thread_startup() 进入到 | 就绪状态(RT_THREAD_READY) |  | 就绪状态的线程被调度器调度后进入 | 运行状态(RT_THREAD_RUNNING) |  | 当处于运行状态的线程调用 rt_thread_delay(),rt_sem_take(),rt_mutex_take(),rt_mb_recv() 等函数或者获取不到资源时,将进入到
 
 | 挂起状态(RT_THREAD_SUSPEND) |  | 处于挂起状态的线程,如果等待超时依然未能获得资源或由于其他线程释放了资源,那么它将返回到 | 就绪状态 |  | 挂起状态的线程,如果调用 rt_thread_delete/detach() 函数,将更改为 | 关闭状态(RT_THREAD_CLOSE) |  | 而运行状态的线程,如果运行结束,就会在线程的最后部分执行 rt_thread_exit() 函数,将状态更改为 | 关闭状态。 | 
 
 
 (二)API
 创建:
 
 rt_thread_t rt_thread_create(const char* name,
                            void (*entry)(void* parameter),
                            void* parameter,
                            rt_uint32_t stack_size,
                            rt_uint8_t priority,
                            rt_uint32_t tick);
 
 关闭:
 
 rt_err_t rt_thread_delete(rt_thread_t thread);
 
 静态初始化:
 
 rt_err_t rt_thread_init(struct rt_thread* thread,
                        const char* name,
                        void (*entry)(void* parameter), void* parameter,
                        void* stack_start, rt_uint32_t stack_size,
                        rt_uint8_t priority, rt_uint32_t tick);
 参数        描述
 thread        线程句柄,它应该是由 rt_thread_init 进行初始化的线程句柄。
 返回        ——
 RT_EOK        线程脱离成功
 -RT_ERROR        线程脱离失败
 
 线程睡眠
 
 rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);
 
 线程挂起
 rt_err_t rt_thread_suspend (rt_thread_t thread);
 
 恢复线程
 rt_err_t rt_thread_resume (rt_thread_t thread);
 
 控制线程
 rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);
 
 线程让出资源
 rt_thread_yield()         当前线程被置于最末
 rt_schedule()        按照优先级放置
 
 获取当前线程
 rt_thread_t rt_thread_self(void);
 
 
 (三)挂起实验
 rt_thread_suspend  可以把某个线程挂起,在某个时候恢复
 尽管官方不怎么推荐使用者使用这个函数,但毕竟还是有相当的实用性,我目前有这个需求,所以进行了一些尝试。
 1-初始化两个线程
 
 
static void rt_init_thread_entry(void *parameter)
{
        rt_thread_t led_thread, printf_thread;
/* Initialization RT-Thread Components */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_init();
#endif
    /* Create led thread */
    led_thread = rt_thread_create("led",
                                  led_thread_entry, RT_NULL,
                                  256, 20, 20);
    if (led_thread != RT_NULL)
        rt_thread_startup(led_thread);
    printf_thread = rt_thread_create("print period",
                                     printf_period, RT_NULL,
                                     256, 20, 20);
    if (printf_thread != RT_NULL)
        rt_thread_startup(printf_thread);
}
 2-在printf控制台打印线程里面每次循环都挂起一次
 
 // led thread entry
static void printf_period(void *parameter)
{
    rt_kprintf("heart break start\n");
    while (1)
    {
        rt_kprintf("heart break\n");
        //        
        rt_thread_suspend(rt_thread_self());
    }
}
 3-在led线程里面唤醒
 
 static void led_thread_entry(void *parameter)
{
    rt_hw_led_init();
    rt_kprintf("start\n");
    while (1)
    {
        rt_hw_led_on();
        rt_thread_delay(RT_TICK_PER_SECOND);
        rt_hw_led_off();
        rt_thread_delay(RT_TICK_PER_SECOND);
        rt_thread_resume(printf_thread);
    }
}
 然而奇怪的事情发生了,串口每隔1s时间打印一串字符,并不是如我想象的那样打印一次立即挂起。
 
 (四)解决方法
 仔细查看文档后发现,挂起是不能够立即生效的,想要立即生效要进行上下文调度,可以用rt_schedule 引起这个调度:
 
 。
static void printf_period(void *parameter)
{
    rt_kprintf("heart break start\n");
    while (1)
    {
        rt_kprintf("heart break\n");
        //        
        rt_thread_suspend(rt_thread_self());
        rt_schedule();
    }
}
 |