(一)状态
线程通过调用函数 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();
}
}
。
|