Linux内核线程真的是内核进程吗?

Ell*_*tus 24 linux process kernel thread linux-kernel

我在很多地方读到 Linux 为 Java VM 中的每个用户线程创建一个内核线程。(我看到术语“内核线程”以两种不同的方式使用:

  1. 为执行核心操作系统工作而创建的线程和
  2. 操作系统知道并安排执行用户工作的线程。

我说的是后一种。)

内核线程是否与内核进程相同,因为 Linux 进程支持父子进程之间的共享内存空间,还是真的是一个不同的实体?

Tot*_*tor 34

文档可能非常混乱,所以这里是“真正的”Linux 模型:

  • 在 Linux 内核中,可以运行(和调度)的东西称为“进程”,
  • 每个进程都有一个系统唯一的进程 ID (PID) 和一个线程组 ID (TGID),
  • “正常”进程的 PID=TGID 并且没有其他进程共享此 TGID 值,
  • “线程化”进程是一个 TGID 值被其他进程共享的进程,
  • 共享相同 TGID 的多个进程也至少共享相同的内存空间和信号处理程序(有时更多),
  • 如果一个“线程”进程的PID=TGID,它可以被称为“主线程”,
  • getpid()从任何进程调用将返回其 TGID(=“主线程”PID),
  • gettid()从任何进程调用将返回其 PID (!),
  • 可以使用clone(2)系统调用创建任何类型的进程,
  • 进程之间共享的内容是通过将特定标志传递给clone(2),
  • 您可以列出文件夹的数字名称ls /proc以及/proc/NUMBERTGID,
  • 文件夹的数字名称/proc/TGID/task/proc/TGID/task/NUMBERPID 一样,
  • 即使您没有看到每个现有的 PID ls /proc,您仍然可以使用cd /proc/any_PID.

结论:从内核的角度来看,只有进程存在,每个进程都有自己唯一的PID,所谓的线程只是一种不同类型的进程(至少与一个或多个共享相同的内存空间和信号处理程序)其他)。

注意: Linux 中“线程”概念的实现导致了词汇混乱,如果getpid() 对你撒谎并没有按照你的想法去做,那是因为它的行为遵循 POSIX 兼容性(线程应该共享一个公共 PID) .

  • *建议:* 使用“任务”一词可能有助于指代可运行的东西,而不会过多地陷入进程/线程混淆。 (2认同)

Dan*_*man 28

Linux 上的线程和进程之间绝对没有区别。如果您查看clone(2),您将看到一组标志,用于确定线程之间共享的内容和不共享的内容。

经典进程只是不共享任何内容的线程;你可以在 Linux 下分享你想要的组件。

其他操作系统实现的情况并非如此,它们之间存在更多实质性差异。


Kyl*_*nes 19

线程是 Linux 下的进程。它们是用clone系统调用创建的,它返回一个进程 ID,可以通过kill系统调用发送信号,就像一个进程一样。线程进程在ps输出中可见。该clone调用传递它确定有多少父进程的环境与线程进程共享的标志。

  • man `pthreads(7)` 说,对于当前的 NPTL(本地 POSIX 线程库)实现,“进程中的所有线程都放在同一个线程组中;线程组的所有成员共享同一个 PID。” 在过时的 LinuxThreads 实现中,每个“线程”都有自己的 PID。 (3认同)