当前位置: 首页 > news >正文

线程管理特点 线程属性 线程状态之间切换

线程管理特点 线程属性 线程状态之间切换

​ RT-Thread是支持多任务的操作系统,多任务是通过多线程的方式实现。线程是任务的载体,是RT-Thread中最基本的调度单位

​ 线程在运行的时候,它自己会认为自己独占CPU运行

​ 线程执行时的运行环境成为上下文,具体来说就是各个变量和数据,包括所有寄存器变量,堆栈,内存信息等,

线程管理特点

​ RT-Thread线程管理的主要功能是对线程进行管理和调度,系统中总共存在两类线程:系统线程用户线程我们的重点是在用户线程,系统线程是由RT-Thread内核创建的线程,用户线程是由应用程序创建的线程,这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除。

​ 内核对象容器 = 用双向链表做成的 “分类货架”,用来收纳同一种类的所有内核对象,方便内核增、删、挨个遍历检查。

​ RT-Thread的线程调度器是抢占式的,主要工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到CPU的使用权.

​ 当调度器线程切换时,先将当前线程上下文保存起来(保护现场),当再切回到这个线程时,线程调度器将该线程的上下文信息恢复(恢复现场)。

线程工作机制

线程控制块(本质就是结构体)

线程控制块是由结构体struct rt_thread表示,线程控制块是操作系统用于管理线程的一个数据结构,它会存放线程的一些信息,例如优先级,线程名称,线程状态等,也包含线程与线程之间连接用的链表结构,线程等待事件集合等。

/** * Thread structure */structrt_thread{/* rt object */charname[RT_NAME_MAX];/**< 给线程起的名字是一个char 型的数组 */rt_uint8_ttype;/**type = 定身份:告诉我它是线程、定时器, 还是别的资源RT-Thread 提前定义了一系列宏,用不同数字代表不同对象类型,举几个最常见的: #define RT_Object_Class_Thread 0x01 // 线程 #define RT_Object_Class_Timer 0x02 // 定时器 #define RT_Object_Class_Semaphore 0x03 // 信号量 #define RT_Object_Class_MessageQueue 0x04 // 消息队列 */rt_uint8_tflags;/**< thread's flags *//* flags 也是 1 字节(8 个二进制位),它不是存一个数字,而是把每一个二进制位当成一个独立的 “开关” 特点:动态变化。线程运行、挂起、退出,这些状态切换,本质就是 flags 里的 “开关” 在不断切换。 flags 主要记录两大类信息:线程当前运行状态(运行、就绪、挂起、关闭等) 线程固有属性(静态创建 / 动态创建、调度属性等) 2. 结合线程状态讲解(对应你 list_thread 的观测结果) 我们之前看到线程有这些状态:running、ready、suspend、closed,全部由 flags 中的状态位来表示。 内核同样用宏定义每一个 “开关” 的含义,节选常用状态标志: #define RT_THREAD_RUNNING 0x01 // 线程正在运行 #define RT_THREAD_READY 0x02 // 线程处于就绪态 #define RT_THREAD_SUSPEND 0x04 // 线程被挂起 #define RT_THREAD_CLOSE 0x08 // 线程已关闭(退出) 线程显示 running CPU 正在执行该线程,flags 中 RT_THREAD_RUNNING 这一位置 1。 线程显示 suspend 比如 timer 线程、调用了 rt_thread_mdelay() 的线程,RT_THREAD_SUSPEND 位置 1。 线程执行完 return 变为关闭态 RT_THREAD_CLOSE 位置 1,同时 list_thread 会过滤掉这类线程。 3. 除了状态,还存 “对象属性” flags 里除了运行状态,还会标记线程的创建方式等固有属性: 标记该线程是 静态线程(rt_thread_init)还是 动态线程(rt_thread_create); 标记线程是否允许被抢占、是否是系统内核线程等。 比如系统 timer、tidle0 是静态线程,对应的属性位会固定置 1; 你自己用 rt_thread_create 创建的线程,动态属性位会置 1。 */#ifdefRT_USING_MODULEvoid*module_id;/**< id of application module */#endif/* RT_USING_MODULE */rt_list_tlist;/**< the object list */rt_list_ttlist;/**< the thread list *//* 线程执行的核心(栈+入口) */void*sp;/**< 栈指针 线程上下文切换的核心:线程切出时,CPU寄存器存在栈里,sp保存当前栈顶地址*/void*entry;/**< 线程入口函数 内核启动线程时从这个地址开始执行 */void*parameter;/**< 入口函数的参数 类比一下就是rt_thread_create的第三个参数。一般传RT_NULL,这就是为什么入口参数要传带void*参数的原因内核会强制把这个字段传给入口 */void*stack_addr;/**< 栈内存的起始地址 */rt_uint32_tstack_size;/**< 栈大小 *//* error code */rt_err_terror;/**< 线程错误码:线程操作的返回值存在这里(比如等待信号量超时) */rt_uint8_tstat;/**< 线程状态核心调度字段: 0-初始状态(刚create还没有startup) 1-就绪态(等待调度) 2-运行态(正在CPU上跑) 3-挂起/阻塞态(延时,等待资源) 4-关闭状态*//*单核MCU先不管.这个是SMP多核支持*/#ifdefRT_USING_SMPrt_uint8_tbind_cpu;/**< thread is bind to cpu */rt_uint8_toncpu;/**< process on cpu */rt_uint16_tscheduler_lock_nest;/**< scheduler lock count */rt_uint16_tcpus_lock_nest;/**< cpus lock count */rt_uint16_tcritical_lock_nest;/**< critical lock count */#endif/*RT_USING_SMP*//* 优先级调度(RT-Thread实时调度的核心) */rt_uint8_tcurrent_priority;/**< 线程当前优先级 *//*超过32级优先级时用*/#ifRT_THREAD_PRIORITY_MAX>32rt_uint8_tnumber;rt_uint8_thigh_mask;#endif/* RT_THREAD_PRIORITY_MAX > 32 */rt_uint32_tnumber_mask;/*事件集支持*/#ifdefRT_USING_EVENT/* thread event */rt_uint32_tevent_set;rt_uint8_tevent_info;#endif/* RT_USING_EVENT *//*信号支持*/#ifdefRT_USING_SIGNALSrt_sigset_tsig_pending;/**< the pending signals */rt_sigset_tsig_mask;/**< the mask bits of signal */#ifndefRT_USING_SMPvoid*sig_ret;/**< the return stack pointer from signal */#endif/* RT_USING_SMP */rt_sighandler_t*sig_vectors;/**< vectors of signal handler */void*si_list;/**< the signal infor list */#endif/* RT_USING_SIGNALS */rt_ubase_tinit_tick;/**<线程初始时的时间片 */rt_ubase_tremaining_tick;/**< 剩余时间片 */#ifdefRT_USING_CPU_USAGErt_uint64_tduration_tick;/**< cpu usage tick */#endif/* RT_USING_CPU_USAGE */#ifdefRT_USING_PTHREADSvoid*pthread_data;/**< the handle of pthread data, adapt 32/64bit */#endif/* RT_USING_PTHREADS */structrt_timerthread_timer;/**< built-in thread timer */void(*cleanup)(structrt_thread*tid);/**< cleanup function when thread exit *//* light weight process if present */#ifdefRT_USING_LWPvoid*lwp;#endif/* RT_USING_LWP */rt_ubase_tuser_data;/**< private user data beyond this thread */};typedefstructrt_thread*rt_thread_t;

void (*cleanup)(struct rt_thread *tid);cleanup函数指针指向的函数,会在线程退出的时候,被Idle线程回调一次,执行用户设置的清理现场等工作。

线程状态

线程属性

线程栈

​ RT-Thread线程具有独立的栈,当进行线程切换时,会将当前线程的上下文存入栈中(压栈),当要线程恢复运行时,再从栈中读取上下文信息(出栈),进行恢复。

线程状态

**初始状态:**当线程刚开始创建rt_thread_creatert_thread_init还没有开始运行的时候就处于初始状态。在初始状态下,线程不参与调度。此状态在RT-Thread中的宏定义为RT_THREAD_INIT

就绪状态:在就绪状态下,线程按照优先级排队,等待被执行;一旦当前线程运行完毕让出处理器,操作系统会马上寻找最高优先级的就绪态线程运行。此状态在RT-Thread中的宏定义为RT_THREAD_REDAY

**运行状态:线程当前正在运行。在单核系统中,只有rt_thread_self()**函数返回的线程处于运行状态;在多核系统中,可能就不止这一个线程处于运行状态。此状态在RT-Thread中的宏定义为RT_THREAD_RUNNING

**挂起状态:**也称阻塞态。它可能因为资源不可用而挂起等待,或线程主动延时一段时间而挂起。在挂起状态下,线程不参与调度。此状态在RT-Thread中的宏定义为RT_THREAD_SUSPEND

**结束状态:**当线程运行结束时将处于关闭状态。关闭状态的线程不参与线程的调度。此状态在RT-thread中的宏定义为RT_THREAD_CLOSE

线程优先级

RT-Thread最大支持256个线程优先级(0-255),值越小优先级越高。通常Cortex-M采用32个优先级。而普遍的项目中一般10个线程就够用了(面经)

时间片

每个线程都有时间片,但是时间片仅仅对优先级相同的线程有效。

[!CAUTION]

线程中不能有陷入死循环的操作,必须有让出CPU使用权的动作,如循环中调用延时函数使线程挂起,或者主动挂起

线程状态之间的切换

[!CAUTION]

就绪状态和运行状态是等同的

http://www.rkmt.cn/news/1514005.html

相关文章:

  • 2026年浙江牛皮纸扑克牌源头厂家专业实力与选型全解析 - 品牌鉴赏官2026
  • 数字信号控制器DSC:融合DSP与MCU优势,实现电机驱动与实时控制
  • 手把手教你给i.MX RT1021核心板刷入MicroPython(附LCD驱动配置)
  • STC89C52RC实测:手把手教你调通433M解码,从计算脉宽到避开EV1527的那些坑
  • 从Griffin-Lim到WaveNet:声码器技术演进的五个关键“顿悟”时刻与未来猜想
  • 【图像融合】基于带有散焦扩散缓解机制的自适应区域分割多焦点图像融合附Matlab代码
  • TSMC18RF工艺下套筒式运放ADS设计实操包:含DC偏置调试、AC响应分析与衬底偏置修正全流程
  • 影刀RPA完全指南_流程执行记录与运行历史日志体系搭建
  • HLS视频下载进阶指南:3步捕获流媒体的高效方案
  • Python 作业:递归遍历文件系统与加密登录系统实现
  • 免费解锁9大网盘高速下载:网盘直链下载助手完整使用指南
  • STM32F103C8T6用HAL库实现USB CDC串口,CubeMX一键生成+中断收发
  • 2026年成都开荒保洁服务哪家强?从众、鑫杰鑫、优净等8家机构综合评测 - 优质品牌商家
  • 给孩子挑增高床垫,我踩过的坑真不少 - 深圳市民HLL
  • 终极网盘直链下载助手:免费解锁9大网盘高速下载的完整教程
  • 如何解决B站视频下载难题:DownKyi免安装版全攻略
  • 3个关键功能,让Snap Hutao成为你原神冒险的最佳伙伴
  • 2026年研磨液实力厂家:广东金刚石粗磨精磨研磨液与镜面抛光液生产商深度解析 - 品牌发掘
  • 2026年成都四害消杀市场格局分析:从灭鼠到白蚁防治的行业实测与趋势解读 - 优质品牌商家
  • 从Flask到Scrapy:盘点那些用Python Hook提升开发效率的真实场景与避坑指南
  • MC9S08GT系列8位MCU:低功耗架构与丰富外设的嵌入式经典设计解析
  • Zotero GPT终极指南:如何用AI智能插件5分钟打造高效文献助手
  • 3分钟上手:英雄联盟玩家的智能游戏助手完全指南
  • AI 驱动的会议效率提升:从语音转写到行动项提取的工程实践
  • 5分钟解决日文游戏乱码:Locale-Emulator终极配置指南
  • 56800TDC开发套件实战指南:从硬件安装到CodeWarrior环境搭建
  • 2026年上海松江区权威金条回收+银条回收机构推荐:称重准 报价实 - 沪上贵金属口碑推荐官
  • 别再死记硬背公式了!图解OpenCV C++灰度变换:线性、对数、伽马变换的本质与视觉原理
  • 汽车电子MCU选型与开发实战:MPC5646C架构解析与应用指南
  • 别再死记硬背了!用Wireshark抓包实战,帮你彻底搞懂TCP确认与重传(附谢希仁习题解析)