16

我想知道如何区分我正在构建的进程扫描器的内核线程和用户线程。我很难找到这两种类型的良好定义。

我发现内核线程没有自己的内存,因此 /proc/$pid/status 中没有 Vm* 值,并且 /proc/$pid/exe 上的统计信息不返回任何内容。

因此,我认为如果进程没有 Vm* 值且没有 inode 编号,我可以识别内核线程。我想错了......我的脚本有时会看到被识别为内核进程的 php-cgi 进程。

如果发现这些错误识别的进程中的大多数都是僵尸,一秒钟后就消失了。所以我实施了一个简单的检查来查看状态是否为“Z”。如果是这样,请忽略它。这为我节省了很多误报,但我仍然收到有关 php-cgi 内核进程的消息。

谁能告诉我如何以正确的方式区分内核线程和用户线程?

4

4 回答 4

13

内核线程和用户空间线程之间有一些明显的区别:

  • /proc/$pid/cmdline对于内核线程为空 - 这是用于区分内核线程ps的方法。top

  • 符号链接没有内核线程的/proc/$pid/exe目标——这是有道理的,因为它们在文件系统上没有相应的可执行文件。

    更具体地说,readlink()系统调用返回ENOENT“没有这样的文件或目录”),尽管链接本身存在,以表示该进程的可执行文件不存在(并且从未存在)的事实。

    因此,检查内核线程的可靠方法应该是调用readlink()/proc/$pid/exe检查其返回码。如果成功,$pid则为用户进程。如果它以 失败ENOENT,那么额外的stat()on/proc/$pid/exe应该可以将内核线程的情况与刚刚终止的进程区分开来。

  • /proc/$pid/status缺少大多数内核线程的几个字段 - 更具体地说是一些与虚拟内存相关的字段。

于 2012-09-01T20:13:20.207 回答
5

正如您在上面自己的评论中指出的那样,所有用户进程都是 init 进程(pid=1)的后代。内核线程不是 init 进程的后代,因为 init 是一个用户进程,用户进程不能创建内核线程。因此,要检查进程 p 是否是用户进程而不是内核线程,需要对进程图进行操作并评估init dom pdom 是否是Dominator运算符。具体在 Python 中:

def is_user_process(p):
  if (p=='1'):
    print 'User process'
  else:
    pstat = open('/proc/%s/stat'%p).read().split()
    parent = pstat[3]
    if (parent=='1'):
      print 'User process'
    elif (parent=='0'):
      print 'Kernel thread'
    else:
      is_user_process(parent)
于 2012-12-21T04:21:12.770 回答
2

您可以从(参见 proc(5) 手册页)读取线程flags值并检查它是否设置了位标志。/proc/[pid]/statPF_KTHREAD

PF_KTHREADconstant 本身从 2.6.17 开始可用,大约 10 年了,从那时起它的值没有改变

#define PF_KTHREAD      0x00200000  /* I am a kernel thread */

即使包含这个常量include/linux/sched.h(.

于 2019-05-29T23:09:59.000 回答
1

这是在 bash 下工作的版本:

# check if pid is user process and not a kernel thread
is_user_process() {
  if [[ $1 -eq 1 ]]; then
    return 0
  else
    parent=$(grep -e '^PPid:' /proc/$1/status | cut -c6-)
    if [[ $parent -eq 1 ]]; then
      return 0
    elif [[ $parent -eq 0 ]]; then
      return 1
    else
      is_user_process $parent
    fi
  fi
}

使用它做

~$ is_user_process `pgrep kthreadd` || echo "kthreadd is kernel process"

这至少对我来说是第一个有用的解决方案,感谢 python 版本的 er0。

于 2016-06-10T21:57:51.870 回答