Table of Contents
Linux 进程与线程的关系

Linux 中其实并不区别进程和线程,都用task_struct来描述,可以说 它们之间的联系大于区别。

创建进程的接口是fork(), 创建线程的接口是pthread_create(), 但是它们最终都是调用的clone()系统调用, 只是参数不同而已。

当一个进程/线程发起创建线程的请求时,不像创建进程那样重新申请mm_struct 和打开的文件等结构, 而是直接将指针赋值为父进程的值,所以它和父进程共享同一个 地址空间这些。

上面说的父进程,因为没有父线程的概念,如果创建线程的task_struct也是一个 线程,那么它的地址空间也是最终指向某个进程的,所以父亲和新的线程就是同等 地位了。

再说说 PID,PID 能够唯一的标识一个进程,一个进程下所有的线程的 PID 都与父进程 相同,那么问题来了,如何标识线程的从属关系呢?

task_struct.tgid标识自己所归属的进程 ID,或者叫主线程 ID,反正就是地址空间 的真正来源。 而进程如何知道自己创建了哪些线程呢?, 通过task_struct.children 链表来查找,但这里面即有子进程又有线程,需要过滤。

有的地方会使用一个名词 管理线程, 其实就是线程共享的地址空间这些的原主。

内核线程

内核线程是一种特殊的进程,当然也是用task_struct来描述,内核线程的特殊点:

  1. mm成员=NULL,没有用户空间的数据,不能访问用户空间
  2. 每个内核线程有私有数据,用set_child_tid成员指向, 是一个struct kthread结构,用to_kthread()来访问私有数据

内核线程也像普通线程一样参与调度,其创建的地方在内核,使用kthread_create() 创建,不能由用户态创建。

内核线程一般负责执行一些内核任务,比如软中断 就有一个内核线程,来专门执行到来中断的服务函数中不着急的部分。


创建于: 2023-05-10T20:51:49, Lastmod: 2023-09-24T18:08:59