中级篇_05_空闲线程和阻塞延时的实现

对空闲线程的理解

  空闲线程对于一个实时操作系统来说是十分重要的。因为线程会因为需要而主动放弃对CPU的使用,而恰好当前所有线程都放弃对CPU的使用,这时候就需要一个保底的线程----优先级最低的空闲线程

空闲线程的实现

    空闲线程也是一个线程,同样是调用rt_thread_init函数创建的。

static struct rt_thread idle;
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE];

static void rt_thread_idle_entry(void *parameter)
{
#ifdef RT_USING_IDLE_HOOK
    rt_size_t i;
#endif

    while (1)
    {

#ifdef RT_USING_IDLE_HOOK
        for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
        {
            if (idle_hook_list[i] != RT_NULL)
            {
                idle_hook_list[i]();
            }
        }
#endif

        rt_thread_idle_excute();
    }
}

/**
 * @ingroup SystemInit
 *
 * This function will initialize idle thread, then start it.
 *
 * @note this function must be invoked when system init.
 */
void rt_thread_idle_init(void)
{
    /* initialize thread */
    rt_thread_init(&idle,
                   "tidle",
                   rt_thread_idle_entry,
                   RT_NULL,
                   &rt_thread_stack[0],
                   sizeof(rt_thread_stack),
                   RT_THREAD_PRIORITY_MAX - 1,
                   32);

    /* startup */
    rt_thread_startup(&idle);
}

  这里还牵扯到钩子函数,嗯~我以后有机会也会详细对这一部分说一下我的理解的。

对阻塞延时的理解

  阻塞延时,他和我们之前使用的延时的区别就是:
    1.阻塞延时是放弃CPU的控制,而之前的延时方式是强制CPU不做有效的操作而实现延时。
    2.很明显阻塞延时需要统计阻塞时间。
  

阻塞延时的实现

1.需要挂起当前函数。
2.需要计算恢复就绪态的时间。
3.线程的切换。

支持修改当前线程的状态

struct rt_thread
{
    /* rt object */
    char        name[RT_NAME_MAX];                      /**< the name of thread */
    rt_uint8_t  type;                                   /**< type of object */
    rt_uint8_t  flags;                                  /**< thread's flags */
    ...
    ...
    rt_uint8_t  stat;                                   /**< thread status */
    ...
    ...
};
/*
 * thread state definitions
 */
#define RT_THREAD_INIT                  0x00                /**< Initialized status */
#define RT_THREAD_READY                 0x01                /**< Ready status */
#define RT_THREAD_SUSPEND               0x02                /**< Suspend status */
#define RT_THREAD_RUNNING               0x03                /**< Running status */
#define RT_THREAD_BLOCK                 RT_THREAD_SUSPEND   /**< Blocked status */
#define RT_THREAD_CLOSE                 0x04                /**< Closed status */
#define RT_THREAD_STAT_MASK             0x0f

  线程有可以记录自己的状态statu的时候,才是可以区别自己状态的时间。

初始态
就绪态
阻塞态
关闭态

如你看到的,挂起态和阻塞态其实是同一种状态
我们通过修改thread->stat = RT_THREAD_INIT;这样的语句来改变线程的状态,

支持记录线程恢复就绪态时间统计

struct rt_thread
{
    /* rt object */
    char        name[RT_NAME_MAX];                      /**< the name of thread */
    rt_uint8_t  type;                                   /**< type of object */
    rt_uint8_t  flags;                                  /**< thread's flags */
    ...
    ...
    rt_ubase_t  remaining_tick;                         /**< remaining tick */
    ...
    ...
};

 通过修改每个线程控制块内的remaining_tick,可以将线程需要延时的时间和系统的滴答时钟联系起来,所以,我们在视频中会听到关于系统的最小的运行时间单位这样的表述。

支持线程的切换

  这时系统还不支持多优先级,但是我们已经了解过关于线程切换的相关知识了。我们是可以使系统可以进行线程切换的,大概示意如下:

thread one thread idle thread two 挂起 调度 调度 挂起 调度 调度 挂起 thread one thread idle thread two

接下来就是优先级了,优先级需要考虑的重要问题:

  • 调度程序是怎么在一堆线程中找到最需要执行的线程?
  • 编程时候怎么注意什么,可以尽可能避免BUG?
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值