当前位置:   article > 正文

20190927(8)RT-Thread 线程管理源码解读(5)启动/控制及相对重要的函数说明_rt_thread_control rt_thread_ctrl_close

rt_thread_control rt_thread_ctrl_close
目的:

1 根据源码讲解启动挂起的函数内容
2 说明一些跟线程调用相关的函数

RT_THREAD_INIT 线程通过调用函数 rt_thread_create/init() 进入到初始状态
RT_THREAD_READY 初始状态的线程通过调用函数 rt_thread_startup() 进入到就绪状态
RT_THREAD_RUNNING 就绪状态的线程被调度器调度后进入运行状态
RT_THREAD_SUSPEND 当处于运行状态的线程调用 rt_thread_delay(),rt_sem_take(),rt_mutex_take(),rt_mb_recv() 等函数或者获取不到资源时,将进入到挂起状态
RT_THREAD_CLOSE rt_thread_delete/detach() 函数,将更改为关闭状态; 而运行状态的线程,如果运行结束,就会在线程的最后部分执行 rt_thread_exit() 函数,也将状态更改为关闭状态

#define RT_EOK 0 /* 无错误 */ 
#define RT_ERROR 1 /* 普通错误 */ 
#define RT_ETIMEOUT 2 /* 超时错误 */ 
#define RT_EFULL 3 /* 资源已满 */ 
#define RT_EEMPTY 4 /* 无资源 */ 
#define RT_ENOMEM 5 /* 无内存 */ 
#define RT_ENOSYS 6 /* 系统不支持 */ 
#define RT_EBUSY 7 /* 系统忙 */ 
#define RT_EIO 8 /* IO 错误 */ 
#define RT_EINTR 9 /* 中断系统调用 */ 
#define RT_EINVAL 10 /* 非法参数 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

正文
1 启动线程 re_thread_startup()
/**
 * This function will start a thread and put it to system ready queue
 *
 * @param thread the thread to be started
 *
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
 */
rt_err_t rt_thread_startup(rt_thread_t thread)
{
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT); //没做初始化的无法启动
    RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);//确保线程类型的正确性

    /* set current priority to init priority */
    thread->current_priority = thread->init_priority; //启动时默认当前优先级为初始设定的优先级

    /* calculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32 
    thread->number      = thread->current_priority >> 3;            /* 5bit */
    thread->number_mask = 1L << thread->number;
    thread->high_mask   = 1L << (thread->current_priority & 0x07);  /* 3bit */
#else
    thread->number_mask = 1L << thread->current_priority;
#endif

    RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",
                                   thread->name, thread->init_priority)); //打印日志
    /* change thread stat */
    thread->stat = RT_THREAD_SUSPEND; //进入挂起状态
    /* then resume it */
    rt_thread_resume(thread); //使线程恢复运行
    
    if (rt_thread_self() != RT_NULL) //该函数将返回当前线程的线程对象句柄
    {
        /* do a scheduling */
        rt_schedule();//该函数将执行一次调度。它将选择一个具有最高优先级的线程,然后切换运行
    }

    return RT_EOK;
}
RTM_EXPORT(rt_thread_startup);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

2. rt_thread_control 线程控制
/**
 * This function will control thread behaviors according to control command.
 *
 * @param thread the specified thread to be controlled
 * @param cmd the control command, which includes
 *  RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread; //改变线程优先级
 *  RT_THREAD_CTRL_STARTUP for starting a thread; //启动线程
 *  RT_THREAD_CTRL_CLOSE for delete a thread; //删除线程
 *  RT_THREAD_CTRL_BIND_CPU for bind the thread to a CPU.//针对多核指定线程到特定CPU上
 * @param arg the argument of control command //命令参数
 *
 * @return RT_EOK
 */
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
{
    register rt_base_t temp;

    /* thread check */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);//判断对象类型是否符合要求

    switch (cmd)
    {
    case RT_THREAD_CTRL_CHANGE_PRIORITY:
        /* disable interrupt */
        temp = rt_hw_interrupt_disable(); //关闭中断

        /* for ready thread, change queue */
        if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY) //确保线程处于就绪状态
        {
            /* remove thread from schedule queue first */
            rt_schedule_remove_thread(thread);//先将线程移出去

            /* change thread priority */
            thread->current_priority = *(rt_uint8_t *)arg;//修改优先级

            /* recalculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
#else
            thread->number_mask = 1 << thread->current_priority;
#endif

            /* insert thread to schedule queue again */
            rt_schedule_insert_thread(thread);//重新加入
        }
        else
        {
            thread->current_priority = *(rt_uint8_t *)arg;

            /* recalculate priority attribute */
#if RT_THREAD_PRIORITY_MAX > 32
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
#else
            thread->number_mask = 1 << thread->current_priority;
#endif
        }

        /* enable interrupt */
        rt_hw_interrupt_enable(temp);
        break;

    case RT_THREAD_CTRL_STARTUP:
        return rt_thread_startup(thread);

#ifdef RT_USING_HEAP
    case RT_THREAD_CTRL_CLOSE:
        return rt_thread_delete(thread);
#endif

#ifdef RT_USING_SMP //多核处理器
    case RT_THREAD_CTRL_BIND_CPU:
    {
        rt_uint8_t cpu;

        if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
        {
            /* we only support bind cpu before started phase. */
            return RT_ERROR;
        }

        cpu = (rt_uint8_t)(size_t)arg;
        thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu; //指定CPU
        break;
    }
#endif /*RT_USING_SMP*/
    default:
        break;
    }

    return RT_EOK;
}
RTM_EXPORT(rt_thread_control);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

3. 其他线程使用相关函数

rt_thread_self() 获取当前线程句柄
rt_thread_yield() 让出CPU使用权,将自身移动到同级别链表尾部
rt_thread_schedule() 也是出让 CPU 使用权,但是区别是一不会移动至链表尾部,二如果没有比该线程高优先存在就继续执行任务
rt_thread_sleep() / delay() / mdelay() 线程睡眠
rt_thread_suspend() 线程挂起(用户最好不用)
rt_thread_resume() 恢复线程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/67329
推荐阅读
相关标签
  

闽ICP备14008679号