Linux 线程相关结构对照表与关系图

Linux 线程相关结构对照表与关系图

目标:精炼说明 thread_infotask_structthread_struct 三者的定位、用途、访问方式与典型源码位置,并给出图示与观测点位。

代码树:kernel-4.4.94


1. 三者对照表(用途与访问)

结构 主要用途 典型字段/内容 存放位置 访问方式 典型源码位置
thread_info 入口/返回热路径的轻量线程元信息;快速判定调度/信号等 flags(TIF_*)preempt_count、指向 task_struct 伴随"每线程内核栈"的固定位置(多为栈底),依架构而定 汇编/内核可通过 sp 掩码/移位 O(1) 获取;C 侧 task_thread_info() arch/*/include/asm/thread_info.hinclude/linux/sched.h
task_struct 进程/线程的完整描述符;跨子系统的核心对象 调度(state/prio/sched_class/se/rt/dl)、mmfilesfssignal/sighand、关系链、凭证、安全等 独立分配的内核对象(含 stack 指针) 通过 currentthread_info->task 获取;task->stack 可回到 thread_info include/linux/sched.h(定义);kernel/fork.c(创建/复制)
thread_struct 寄存器上下文/FPU/TLS,供上下文切换与栈初始化使用 架构专属寄存器集、FPU 状态、TLS、返回地址 嵌在 task_struct 中(task_struct.thread switch_to() / copy_thread_tls() 架构代码读写 arch/*/kernel/process.carch/*/include/asm/processor.h

2. 关系图与内核栈布局(示意)

text 复制代码
高地址                                                      低地址
┌──────────────────────────────────────────────────────────────┐
│                      task_struct(独立分配的对象)           │
└──────────────────────────────────────────────────────────────┘
                 │
                 │ task->stack 指向内核栈基址(架构约定)
                 ▼
┌──────────────────────────────────────────────────────────────┐ ← 高地址(栈顶,初始SP)
│                  内核栈(每任务私有,大小=THREAD_SIZE)       │
│    ··· 运行时压入帧、保存寄存器(pt_regs)、异常帧等 ···      │
│                                                              │
│    (有的架构在栈底或单独区域存放 thread_info)              │
└──────────────────────────────────────────────────────────────┘ ← 低地址(栈底)
┌──────────────────────────────────────────────────────────────┐
│               thread_info(常位于栈底或附近)                │
│  - flags/TIF_*/preempt_count/sp 等快速访问域                 │
│  - 指向 task_struct(便于 current/this_thread_info 获取)     │
└──────────────────────────────────────────────────────────────┘

(注:不同架构的 thread_info 定位与 THREAD_SIZE/THREAD_SIZE_ORDER 定义不同;详见各架构的 `thread_info.h`。)

3. 为什么需要 thread_info

  • 低开销热路径:在异常/中断/系统调用入口与返回时,汇编代码需快速判断 TIF_NEED_RESCHEDTIF_SIGPENDING 等,无需先解引用庞大的 task_struct
  • 早期可用:在某些早期阶段取用 task_struct 不安全,而 thread_info 随栈可稳定访问。
  • 历史与兼容:4.4.94 时代多架构采用"thread_info 在栈"的模式统一了 current_thread_info() 的获取;后续部分架构引入 CONFIG_THREAD_INFO_IN_TASK(与本树不同)。

4. 源码索引(对照)

  • 访问宏:include/linux/sched.h
    • task_thread_info(task)task_stack_page(task)end_of_stack(task)
  • 架构定义:arch/*/include/asm/thread_info.h
    • struct thread_info 字段与 THREAD_SIZE/THREAD_SIZE_ORDER(如 ARM: PAGE_SIZE << THREAD_SIZE_ORDER,x86_64: arch/x86/include/asm/page_64_types.h)。
  • 栈/返回路径:arch/*/kernel/entry.S
    • 例如 arch/mn10300/kernel/entry.SGET_THREAD_INFOTIF_ALLWORK_MASK 检查;系统调用返回路径基于 thread_info->flags 做调度/信号处理。
  • 创建与初始化:kernel/fork.c
    • copy_thread_tls() 初始化子线程的内核栈与返回路径(如 ret_from_fork);dup_task_struct() 分配 task_struct 与栈。
  • 上下文切换:arch/*/kernel/process.c, switch_to()
    • 读写 task_struct.threadthread_struct)以保存/恢复寄存器与 FPU/TLS。

5. 观测与验证建议

  • Ftrace:
    • sched_switchsched_process_forksched_process_exec 可辅助关联"线程切换/创建/换映像"与 thread_info.flags 的时机。
  • /proc 快照:
    • cat /proc/<pid>/sched 查看任务策略与统计;/proc/sched_debug 查看 CFS 队列与 vruntime
  • 代码交叉验证:
    • 架构入口的 entry.Sthread_info.h,配合 sched.h 宏,确认"sp → thread_info → current"的访问路径。

6. 小结

  • thread_info 为"快而近"的线程元信息,服务于入口/返回热路径与抢占/信号判定;
  • task_struct 为"全量"的进程/线程描述符,跨子系统管理任务的全部状态;
  • thread_struct 为"架构上下文",在切换与初始化中保存寄存器/FPU/TLS;三者分层协作,既兼顾性能也满足可维护性。
相关推荐
A小辣椒14 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒17 小时前
TShark:基础知识
linux
AlfredZhao20 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩2 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言