做人呢,最紧要就系开心啦

Linux内核之进程6: 深度睡眠

791次阅读
没有评论

1. 深度睡眠特点及存在原因

深度睡眠 TASK_UNINTERRUPTIBLE:不可被信号唤醒;

浅度睡眠 TASK_INTERRUPTIBLE:唤醒方式,等到需要的资源,响应信号;

深度睡眠场景:

有些场景是不能响应信号的,比如读磁盘过程是不能打断的,NFS 也是;

Linux 内核之进程 6: 深度睡眠

执行程序过程中,可能需要从磁盘读入可执行代码,假如在读磁盘过程中,又有代码需要从磁盘读取,就会造成嵌套睡眠。逻辑做的太复杂,所以读磁盘过程不允许打断,即只等待 IO 资源可用,不响应任何信号;

应用程序无法屏蔽也无法重载 SIGKILL 信号,深度睡眠可以不响应 SIGKILL kill- 9 信号;

深度睡眠案例

Linux 内核之进程 6: 深度睡眠

此时该进程读 IO 过程,是无法用 kill - 9 杀死的;

一般绝大部分场景,都设置为浅睡眠

Linux 内核之进程 6: 深度睡眠

ps aux: D+

深度睡眠进程显示 D + 状态

2. 深度睡眠对 load average 的影响

top load average:
cat /dev/global_fifo
Kill -2 pid
Kill -9 pid

无法杀死,load average 变大,CPU 依然空闲;

多加一个进程

cat /dev/global_fifo

load average 继续变大,CPU 依然空闲;

load
average:包括 CPU 消耗和 IO 的总预期,此时虽然不消耗 CPU,但是等待 IO 消耗了时间,load
average 显示的是随时间变化的平均负载预期;

D 状态会增加 load average;

对于同一个程序,不同执行环境:

执行性能 =APP(消耗 CPU)+DISK(I/ O 消耗);

3.TASK_KILLABLE

只响应致命信号 D 状态;

不跳转 APP 响应信号,不会产生递归睡眠;

__set_current_state(TASK_KILLABLE);

可以响应信号 9

Linux 内核之进程 6: 深度睡眠

kill -2 pid ? // 发现被杀死,什么原因呢

dmesg

Linux 内核之进程 6: 深度睡眠

git grep "complete_signal"

Linux 内核之进程 6: 深度睡眠

满足 sig_fatal,判断独占 signal_pending,符合条件,内核添加一个 SIGKILL 信号,导致 - 2 变成 -9

Linux 内核之进程 6: 深度睡眠

条件:

Linux 内核之进程 6: 深度睡眠

#define sig_fatal(t, signr) \\

(!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \\
(t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)

满足信号:不忽略,也不是 stop,行为缺省。(缺省信号定义基本就是死,Core/Term 等)

那么添加 SIGKILL 信号;

与 fatal_signal() 必须 9 信号,不一样;

Ps: 如果应用层捕获了 2 信号,那么就不满足 sig_fatal,kill - 2 杀不死了;

综上, 满足 sig_fatal,kill - 2 可以杀 TASK_KILLABLE 进程;

正文完
 
admin
版权声明:本站原创文章,由 admin 2022-01-04发表,共计1142字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)