查看 proc 手册页(http://man7.org/linux/man-pages/man5/proc.5.html) 可以/proc/<pid>/stat
通过查看flags
值 ( PF_KTHREAD
)来检测哪些进程是内核线程
flags %u (%lu before Linux 2.6.22)
(9) The kernel flags word of the process. For bit
meanings, see the PF_* defines in the Linux kernel
source file include/linux/sched.h. Details depend
on the kernel version.
这个进程标志 ( PF_KTHREAD
) 在内核版本 2.6.18(在 RHEL5 中使用)中似乎不存在,该值被另一个标志使用。
有没有其他方法来确定pid是否是内核线程?
答案1
启发式地,请参阅https://stackoverflow.com/questions/12213445/identifying-kernel-threads
ps
和top
(来自procps-3.28)使用“无命令行”作为检查,并且不了解PF_KTHREAD
.这就是触发他们添加[``]
到进程名称的原因,它是不是实际进程名称的一部分。由于命令行受进程本身的控制,因此它可能已被修改。
这取决于您需要回溯多远(2.4?2.2?)。对一些系统的快速搜索表明没有明显的共同标志(字段 9 /proc/PID/stat
)
在 2.6.x 后期,您可以通过父 PID 为 0 来猜测[kthreadd]
,通常 PID 为 2,并且所有线程都将是其子线程(init
也可能具有 PPID=0)。或者可能(早期的 2.6.x?) a[kthread]
代替,但不是 PID 2,但它可能只是大多数而不是所有线程的父级。
另一种方法是检查/proc/PID/maps
(用户空间内存映射),对于内核线程来说,这将是空的——因此只要进程标志(in /proc/PID/stat
)不是&(PF_EXITING)
,/proc/PID/maps
空就是一个很好的指示器。请注意,您必须实际读取maps
,而不仅仅是stat()
它,因为大小被错误报告为 0;并且您还必须获得许可,如果没有,它可能会显示为空而不会导致错误。
for pp in /proc/[0-9]*; do
if [ -z "$(< $pp/maps)" ]; then echo ${pp##/proc/}; fi;
done
您可以添加类似的表达式来检查它cmdline
是否也是空的。
答案2
查看/proc
3.8 系列内核上的内核线程条目,显然链接exe
是空的,其中statm
充满了零,status
缺少所有Vm*
条目并且也是maps
空的。
也许其中一些适用于有问题的旧内核。