当前位置:首页 > 嵌入式 > Linux阅码场
[导读]1开场白环境:处理器架构:arm64内核源码:linux-5.10.50ubuntu版本:20.04.1代码阅读工具:vimctagscscope无论是任务处于用户态还是内核态,经常会因为等待某些事件而睡眠(可能是等待IO读写完成,也可能等待其他内核路径释放一把锁等)。本文来探讨...

1开场白

环境:
  • 处理器架构:arm64
  • 内核源码:linux-5.10.50
  • ubuntu版本:20.04.1
  • 代码阅读工具:vim ctags cscope
无论是任务处于用户态还是内核态,经常会因为等待某些事件而睡眠(可能是等待IO读写完成,也可能等待其他内核路径释放一把锁等)。本文来探讨一下,任务处于睡眠中有哪些状态?睡眠对于任务来说究竟意味着什么?内核是如何管理睡眠的任务的?我们会结合内核源代码来分析任务的睡眠,力求全方位角度来剖析。

注:由于篇幅问题,文章分为上下两篇,且这里不区分进程和任务,统一使用任务来表示进程。

主要讲解以下内容:

  • 睡眠的三种状态

  • 睡眠的内核原理

  • 用户态睡眠

  • 内核态睡眠

  • 总结

2. 睡眠的三种状态

任务睡眠有三种状态:

浅度睡眠 

中度睡眠 

深度睡眠

2.1 浅度睡眠

进程描述符的state使用TASK_INTERRUPTIBLE表示这种状态。

为可中断的睡眠状态,这里可中断是可以被信号所打断(唤醒)。

这里给出被信号打断/唤醒的代码路径:

kernel/signal.c
SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
->kill_something_info
    ->__kill_pgrp_info
        ->group_send_sig_info
            ->do_send_sig_info
                ->send_signal
                    ->__send_signal  
                        ->complete_signal
                            ->signal_wake_up
                                 -> signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0) 
                                    ->wake_up_state(t, state | TASK_INTERRUPTIBLE)
                                        ->try_to_wake_up
可以看到在信号传递的时候,会通过signal_wake_up唤醒从处于可中断睡眠状态的任务。

2.2 中度睡眠

进程描述符的state使用TASK_KILLABLE表示这种状态。

可以被致命信号所打断。

这里给出被致命信号打断/唤醒的代码路径:

include/linux/sched.h
#define TASK_KILLABLE                   (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)

kernel/signal.c
SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
->kill_something_info
    ->__kill_pgrp_info
        ->group_send_sig_info
            ->do_send_sig_info
                ->send_signal
                    ->__send_signal  
                        ->complete_signal
                         ->
                                if (sig_fatal(p, sig) 
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读
关闭