0

0

Linux 进程卡住了怎么办?

絕刀狂花

絕刀狂花

发布时间:2025-07-18 10:44:01

|

536人浏览过

|

来源于php中文网

原创

linux 系统中,当进程由于网络或磁盘等 i/o 问题而卡住时,通常会进入不可中断睡眠状态(uninterruptible sleep),在 ps 命令中显示为 d 状态。这是因为这些进程正处于内核态的系统调用中,无法立即响应信号,包括 kill -9

Linux 进程卡住了怎么办?

当使用 ps 查看进程列表时,可以看到卡住的进程状态显示为 D。

Linux 进程卡住了怎么办?

根据 man ps 的描述,D 状态表示进程处于不可中断睡眠状态。这种状态的进程无法立即处理任何发送给它的信号,因此无法通过 kill 命令终止。

Linux 进程有两种睡眠状态:

  • Interruptible Sleep(可中断睡眠),在 ps 命令中显示为 S。这种状态的进程可以通过发送信号来唤醒。
  • Uninterruptible Sleep(不可中断睡眠),在 ps 命令中显示为 D。这种状态的进程无法立即处理任何信号,这就是为什么 kill 命令无法终止它们的主要原因。

在 Stack Overflow 上有一个相关的解答,指出 D 状态的进程通常是处于某个内核态的系统调用中。要确定是哪个系统调用以及在等待什么,可以通过 Linux 下的 procfs(即 /proc 目录)查看进程的当前内核调用栈。

通过模拟 JuiceFS 客户端进程(因为 JuiceFS 基于 FUSE,是用户态的文件系统,容易模拟 I/O 故障),我们可以看到 ls 命令卡在了 vfs_fstatat 调用上,这会向 FUSE 设备发送 getattr 请求,并等待回应。如果 JuiceFS 客户端进程被暂停,ls 命令就会卡住。

$ cat /proc/`pgrep ls`/stack
[] request_wait_answer+0x197/0x280
[] __fuse_request_send+0x67/0x90
[] fuse_request_send+0x27/0x30
[] fuse_simple_request+0xcc/0x1a0
[] fuse_do_getattr+0x120/0x330
[] fuse_update_attributes+0x68/0x70
[] fuse_getattr+0x3d/0x50
[] vfs_getattr_nosec+0x2f/0x40
[] vfs_getattr+0x26/0x30
[] vfs_fstatat+0x78/0xc0
[] SYSC_newstat+0x2e/0x60
[] SyS_newstat+0xe/0x10
[] entry_SYSCALL_64_fastpath+0x22/0xcb
[] 0xffffffffffffffff

在这种情况下,按 Ctrl+C 无法退出,但使用 strace 可以唤醒进程并处理之前的中断信号,使其退出。

root@localhost:~# strace -p `pgrep ls`
strace: Process 26469 attached
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=13290, si_uid=0} ---
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
...
tgkill(26469, 26469, SIGINT)            = 0
--- SIGINT {si_signo=SIGINT, si_code=SI_TKILL, si_pid=26469, si_uid=0} ---
+++ killed by SIGINT +++

如果使用 kill -9,也可以终止进程,因为 vfs_lstatat() 等简单的系统调用并没有屏蔽 SIGKILLSIGQUITSIGABRT 等信号。

MiniMax开放平台
MiniMax开放平台

MiniMax-与用户共创智能,新一代通用大模型

下载

在更复杂的 I/O 错误模拟中,给 JuiceFS 配置一个无法写入的存储类型,并挂载后,使用 cp 尝试写入数据,cp 也会卡住。

root@localhost:~# cat /proc/`pgrep cp`/stack
[] request_wait_answer+0x197/0x280
[] __fuse_request_send+0x67/0x90
[] fuse_request_send+0x27/0x30
[] fuse_flush+0x17f/0x200
[] filp_close+0x32/0x80
[] __close_fd+0xa3/0xd0
[] SyS_close+0x23/0x50
[] entry_SYSCALL_64_fastpath+0x22/0xcb
[] 0xffffffffffffffff

cp 卡在 close_fd() 是因为 JuiceFS 的写入操作是异步的,当 cp 调用 write() 时,数据会先缓存在 JuiceFS 客户端进程中,并异步写入后端存储。cp 完成写入后会调用 close 确保数据写入完成,对应 FUSE 的 flush 操作。如果后端存储写入失败,flush 操作会卡住,导致 cp 也卡住。

在这种情况下,按 Ctrl+C 或使用 kill 可以中断 cp 的运行,因为 JuiceFS 实现了文件系统操作的中断处理,让它放弃当前操作(如 flush),返回 EINTR,从而在遇到网络故障时中断访问 JuiceFS 的应用。

如果停止 JuiceFS 客户端进程,使其无法处理任何 FUSE 请求(包括中断请求),则无法通过 kill -9 终止进程,进程状态会变为 D 状态。

root      1592  0.1  0.0  20612  1116 pts/3    D+   12:45   0:00 cp parity /jfs/aaa

此时,可以通过 cat /proc/1592/stack 查看进程的内核调用栈:

root@localhost:~# cat /proc/1592/stack
[] request_wait_answer+0x12d/0x280
[] __fuse_request_send+0x67/0x90
[] fuse_request_send+0x27/0x30
[] fuse_flush+0x17f/0x200
[] filp_close+0x32/0x80
[] __close_fd+0xa3/0xd0
[] SyS_close+0x23/0x50
[] entry_SYSCALL_64_fastpath+0x22/0xcb
[] 0xffffffffffffffff

内核调用栈显示进程卡在 FUSE 的 flush 调用上。只要恢复 JuiceFS 客户端进程,就可以立即中断 cp 并使其退出。

close 这种涉及数据安全性的操作是不可重启的(non-restartable),因此不能被 SIGKILL 等信号随意中断,必须由 FUSE 实现端响应中断操作才能中断。

因此,只要 JuiceFS 客户端进程能够健康响应中断,就不必担心访问 JuiceFS 的应用会卡死。或者,可以通过终止 JuiceFS 客户端进程来结束当前挂载点,中断所有正在访问该挂载点的应用。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

391

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

overflow什么意思
overflow什么意思

overflow是一个用于控制元素溢出内容的属性,当元素的内容超出其指定的尺寸时,overflow属性可以决定如何处理这些溢出的内容。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1735

2024.08.15

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1349

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

702

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

294

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

776

2023.07.05

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

572

2023.07.06

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.8万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Node.js-前端工程化必学
Node.js-前端工程化必学

共19课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号