当前位置:首页>Linux>Linux中这些上下文你知道?

Linux中这些上下文你知道?

  • 2026-09-17 15:28:48
Linux中这些上下文你知道?
大家好,我是王鸽,之前写中断文章的时候,就感觉出现上下文这个词汇很频繁,这个是什么?有哪些分类?差别是什么?

这是 Linux 内核里最经典、面试必考的一组概念,我给你用最清晰、最容易记住的方式讲透。

一句话:上下文 = 当前代码是在什么环境、什么时机、什么权限下被 CPU 执行的。

对驱动来说,最关键就两类:

  1. 进程上下文
  2. 中断上下文

一、进程上下文 vs 中断上下文

1. 进程上下文(Process Context)

就是进程在内核里运行的状态。

  • 场景:系统调用、内核线程、fork/exec 等
  • 是谁在跑:某个具体进程(有 task_struct)
  • 可以做什么:
    • 可以休眠(schedule、mutex、wait_event、copy_from_user…)
    • 可以访问进程地址空间
    • 可以被调度、被抢占(视配置)
  • 特点:
    • 来自用户进程系统调用
    • 可以休眠(msleep、mutex、copy_from_user 等)
    • 有 current 指针(指向当前进程)
    • 有栈:进程内核栈
    • 可以被调度、切换

一句话记:进程上下文 = 可以睡觉、可以调度、有进程背景。

2. 中断上下文(Interrupt Context)

硬件触发中断 → 内核执行中断处理函数。

  • 场景:硬件中断、IRQ handler、tasklet 等(来自硬件中断或软中断 /tasklet/work_struct(硬中断底半部))
  • 是谁在跑:不属于任何进程
  • 绝对不能做的事
    • 不能休眠
      (mutex、msleep、kmalloc(GFP_KERNEL)、copy_from_user…)
    • 不能调度
    • 不能访问用户空间
  • 特点:
    • 执行时间必须极短
    • 用的是中断栈
    • 没有进程信息,current 无效
    • 不能被调度,只能抢占(取决于内核配置)
  • 优先级极高,会抢占进程上下文
  • 只能用自旋锁 spinlock

一句话记:中断上下文 = 不能睡觉、不能调度、必须快进快出。

二、核心区别(一张表搞定)
对比项
进程上下文
中断上下文
归属
属于某个进程(current 有效)
不属于任何进程
能否休眠
可以
不可以
能否调度
可以
不可以
能否访问用户空间
可以
不可以
栈
进程内核栈
中断栈
执行时间
无严格限制
必须很短
常用同步
mutex、semaphore、waitqueue
自旋锁spinlock
、atomic
典型场景
系统调用、设备读写、内核线程
中断处理函数、tasklet、HRtimer

三、除了这两个,Linux 还有哪些「上下文」?

你问的这个非常关键,Linux 不止这两种。

1. softirq 上下文(软中断上下文)

  • 属于中断下半部
  • 性质接近中断上下文:不能休眠、不能调度
  • 比硬中断稍微宽松一点,但仍然不能睡眠

2. tasklet 上下文

  • 基于 softirq
  • 也是原子上下文,不能休眠

3. 原子上下文(Atomic Context)

这是一个统称:

  • 中断上下文
  • softirq
  • tasklet
  • 持有 spinlock 的上下文

只要是不能休眠、不能调度的,都叫原子上下文。

4. 内核线程上下文(Kernel Thread Context)

  • 本质是进程上下文
  • 没有用户空间
  • 可以休眠、可以调度

5. 用户上下文(User Context)

  • 进程在用户态运行
  • 还没进入内核

四、最简单的总结(背这个就够)

  • 进程上下文
    可以睡,可以调度,有进程。
  • 中断上下文
    不能睡,不能调度,无进程,必须快。
  • 原子上下文
    所有不能睡眠的上下文统称(中断、softirq、tasklet、持自旋锁)。
  • 其他:软中断上下文、tasklet 上下文、内核线程上下文、用户上下文。
补充一下:

Linux 内核驱动:判断当前上下文(可直接复制)

#include<linux/kernel.h>#include<linux/interrupt.h>#include<linux/preempt.h>#include<linux/sched.h>/* * 判断当前执行上下文 * 返回值: * 0 = 进程上下文 * 1 = 硬中断上下文 * 2 = 软中断/softirq/tasklet 上下文 */intget_current_context(void){    if (in_irq()) {        /* 硬件中断上下文 */        return 1;    } else if (in_softirq()) {        /* 软中断、tasklet、timer 上下文 */        return 2;    } else {        /* 进程上下文(包括内核线程) */        return 0;    }}EXPORT_SYMBOL(get_current_context);

常用判断宏(驱动里直接用)

  • in_irq()在硬中断上下文 → 返回非 0

  • in_softirq()在软中断 /tasklet/hrtimer → 返回非 0

  • in_interrupt()在任何中断类上下文(硬中断 + 软中断)→ 返回非 0等价:in_irq() || in_softirq()

  • in_atomic()在原子上下文(中断 + 持自旋锁 + 禁止抢占)→ 返回非 0

谢谢阅读点赞收藏!

最新文章

随机文章