从内核角度看Linux 线程和进程的区别

article/2025/10/30 22:59:18

多数人都会讲说线程和进程在内核中是相同的,没有严格地做区分。这样讲是没错了,但对于应用开发者来说,这样讲是有点笼统。本文将从内核角度,分析线程和进程之间的区别,希望能对这一块感兴趣的人提供借鉴意义。

1 数据结构 task_struct

Linux中无论是进程还是线程,只要是调度单元,都通过 struct task_struct表示。这也是为什么讲说进程和线程在内核相同的原因。

struct task_struct有保存有关线程/进程中的一切信息,主要包括有线程/进程状态、与其他线程/进程关系、虚拟内存相关、日志相关、线程/进程限制等。该结构体定义在include/linux/sched.h文件中,感兴趣可以详细阅读

那么,进程和线程在task_struct结构体中是否有标识上的不同?

实际上,在struct task_struct中并没有明确的标识(枚举类型),区分该task是线程还是进程,不过可以通过pid和tgid简单判断当前task是哪种类型。

在该结构体中如下段code所示,全局pid和tgid保存在task_struct结构体中。pid_t一般为int型,即可以同时使用2^{32}不同标识的id。

pid用于标识不同进程和线程。

tgid用于标识线程组id,在同一进程中的所有线程具有同一tgid。tgid值等于进程第一个线程(主线程)的pid值。接着以CLONE_THREAD来调用clone建立的线程,都具有同样的tgid。(后文会详细描述创建过程)

group_leader 线程组中的主线程的task_struct指针。

struct task_struct {
...pid_t pid;pid_t tgid;
...struct *group_leader;
}

那么除了tgid和group_leadr是进程/线程的区别外,还有什么其他的区别么?

进程还是线程的创建都是由父进程/父线程调用系统调用接口实现的。创建的主要工作实际上就是创建task_strcut结构体,并将该对象添加至工作队列中去。而线程和进程在创建时,通过CLONE_THREAD flag的不同,而选择不同的方式共享父进程/父线程的资源,从而造成在用户空间所看到的进程和线程的不同。

2 线程/进程的创建

无论以何种方式创建线程/进程在Linux kernel最终都是调用do_fork接口(定义在kernel/fork.c)

其函数原型为:

long do_fork(unsigned long clone_flags,unsigned long stack_start,unsigned long stack_size,int __user *parent_tidptr,int __user *child_tidptr)
  • clone_flags是一个标志集合,用来指定控制复制过程的一些属性。最低字节指定了在子进程终止时被发给父进程的信号号码。其余的高位字节保存了各种常数。
  • stack_start是用户状态下栈的起始地址。
  • stack_size是用户状态下栈的大小。
  • arent_tidptr和child_tidptr是指向用户空间中地址的两个指针,分别指向父子进程的PID。NPTL(Native Posix Threads Library)库的线程实现需要这两个参数。

do_fork的代码流程图如下所示:

上面流程特别判断了是否是vfork,该接口是vfork接口call下来,在子进程没有执行完前,父进程处于阻塞态。一般用于子进程直接调用execv时使用。因为子进程不需要copy父进程的资源从而减少do_fork时的消耗,不过由于fork增加了写时复制机制,vfork也很少使用。这些不是这篇介绍的重点。

那么拿掉vfork的过程,do_fork主要做了三件事,1 copy_process 2 确定PID 3 wake_up_new_task

wake_up_new_task即是将新创建的线程/进程添加至调度程序的队列中

do_fork主要的一部分工作集中在copy_process中,线程与进程之间的区别也是在该接口中体现,接口的代码流程图如下所示:

当上层以pthread_create接口call到kernel时,clone_flag是有CLONE_PTHREAD标识

但CLONE_PTHREAD标识只在最后一个步骤(设置各个ID、进程关系)时体现:(current为当前进程/线程的task_struct结构体 ,p为新创建的结构体对象)

if (clone_flags & CLONE_THREAD) {p->group_leader = current->group_leader;p->tgid = current->tgid;
} else {p->group_leader = p;p->tgid = p->pid;
}

那么,以我们的理解来看,线程会共享信号、共享虚拟地址空间...又以什么体现呢?

去glibc查询了pthread_create的实现,当call到kernel时的clone_flag如下:

  const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM| CLONE_SIGHAND | CLONE_THREAD| CLONE_SETTLS | CLONE_PARENT_SETTID| CLONE_CHILD_CLEARTID| 0);

所以在创建线程时,clone_flags有其他许多项共同构成,才让我们看出来最终线程与进程间的不同。这些flag主要体现在【分享/复制进程各个部分中】步骤。

这些CLONE_abc的使用方法相似。在这些形如copy_abc的接口中,通过判断该flag标识,决定对内核子系统资源是与父进程/线程公用还是新创建出来。可参考下图。

一开始父进程和子进程对于res_abc指向同一个内容(通过dup_task_struct接口实现,子进程完全copy父进程),然后经过copy_abc程序,当有CLONE_abc标识时,父进程会共享资源,同时res_abc的引用计数+1,当!CLONE_abc时,会创建一个res_abc的副本。

又去glibc查询了fork的clone_flags

CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD

那么线程创建就比进程多CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_THREAD,从这些宏的字面意义上看,子线程会与父线程共享虚拟地址空间、文件、信号等。

每个flag的实现原理基本一致,上文已讨论过,这里仅对具体的哪些资源造成了影响进行分析。

CLONE_VM 为虚拟地址空间

所以子线程会共享父线程的虚拟地址空间(通过struct mm_struct *mm指向实例描述),active_mm当用户线程切换至内核线程时使用,这里不详述。

struct task_struct {
...struct mm_struct *mm;struct mm_struct *active_mm;
...
}

CLONE_FS struct fs_struct *fs 进程当前目录及工作目录

CLONE_SIGHAND struct sighand_struct *sighand 信号及信号处理函数

3 ps -H 命令的显示


http://chatgpt.dhexx.cn/article/FRc1cFmv.shtml

相关文章

java线程与进程的区别是什么?

关于进程与线程的文章早已是非常多了,本文是对我个人过往学习,理解及应用进程与线程的一个总结。此文内容涉及进程线程的区别,什么是进程,什么是线程?希望对大家有所帮助。 java线程与进程的区别是什么? 进程:是并…

Java面试--线程和进程的区别

面试题:线程和进程的区别是什么(招银网络科技、阿里巴巴面试题) 一、线程和进程的区别是什么? 1、进程是一段正在执行的程序,是资源分配的基本单元,而线程是CPU调度的基本单元。 2、进程间相互独立进程&a…

对线程与进程的区别以及对多线程并发的理解

一、线程与进程的区别 先简单说说线程与进程的概念: (1)进程是指一个内存中运行的应用程序,比如在Windows系统中,一个运行的exe就是一个进程。 (2)线程是指进程中的一个执行流程。 区别&…

线程与进程的区别和处理器的调度

(1)进程的概念(Dijkstra) 进程是可并发执行的程序在某个数据集合上的一次计算活动,也是操作系统进行资源分配和调度的基本单位。 (2)进程与程序的联系与区别 ① 程序是指令的有序集合&#x…

多线程(一)线程和进程的区别

目录 🍓 一,进程线和程的概念🍌二,为什么要有线程(1)首先并发编程成为需求(2)虽然进程也可以并编程,但是线程更轻量(3)那么是不是线程创建越多越好…

线程和进程的区别是什么?(2021最新)

首先用一句话概括线程和进程的区别是:进程和线程都是一个时间段的描述,是CPU工作时间段的描述。是运行中的程序指令的一种描述,这需要与程序中的代码区别开来。 做个简单的比喻:进程火车,线程车厢 线程在进程下行进&…

线程和进程的区别和联系

操作系统任何处理线程 1.先描述一个进程(明确出一个进程上面的一些相关的属性) 操作系统里面主要是通过c/c来实现的,此处的描述其实就是用的c语言中的"结构体"(操作系统中描述进程的这个结构体称为"PCB"(process control block)进程控制块。 2.再组…

进程和线程有什么区别?

从用户的角度来看,进程是正在运行的程序实例,而线程是进程中真正执行任务的基本单位。也就是说一个运行的程序至少包含一个进程,一个进程至少包含一个线程,线程不能独立于进程而存在。 进程 进程(Process&#xff09…

线程和进程有什么区别(简单介绍)

线程和进程有什么区别(简单介绍) 简单介绍 一、线程的基本概念 线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可…

线程和进程的区别是什么?

本文转载自知乎 文章目录 1.进程和线程的定义2.二者的区别(解释1)3.两者的区别(解释2) 1.进程和线程的定义 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是…

线程和进程的区别

1、线程和进程的区别 进程:是指一个内存中运行的应用程序(已经在内存中运行的程序). 一个进程都有一个独立的内存空间,一个电脑(手机)可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位; 线…

线程与进程,你真得理解了吗

线程与进程,你真得理解了吗 1 进程与线程的关系和区别2 并行与并发3 线程共享了进程哪些资源 相信大家面试时一定没少被一个问题刁难,那就是进程和线程的区别是什么?这个问题延申开来并不像表面那么简单,今天就来深入一探。 开始…

axure自定义文本框样式

axure中的文本框是我们经常使用的元件,但它本身对样式的设置很有限,不能设置边框样式、阴影等,不能满足我们制作高保真原型的需求,本文给大家介绍一下结合矩形元件自定义文本框样式。(PS:此处的“高保真”指…

html文本框左移动怎么设css,html---文本框样式;

一、一个单行文本框的例子 您的姓名: 您的E_mail: 输入口令: 二、检验用户输入的信息 三、制作一个留言簿 留 言 簿 姓名: E_mail: 留 言 html文本框参考样式 输入框景背景透明: 鼠标划过输入框,输入框…

html 文本域和文本框,html的文本框和文本域样式

如果前边几章学习的比较扎实的话,本节教程就相当容易了。下边先说一下文本框,文本框和文本域都是可以用css进行美化的。比如改变边框精细,颜色,添加背景色、背景图像等。请看下边的实例: .text1 { border:1px solid #f60; color:#03C;} .text2 { border:2px solid #390; w…

[微信小程序专题] 配置文本框样式、排版及点击页面跳转

欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。 问题 如何更改小程序页面中的文本框颜色和边框样式? 如何实现多个文本框的排版? 如何实现点击一个文本框即跳转页面? 我们在使用一个小程序…

php输入文本框样式,【js】:检测用户输入、文本框默认样式设置、设计表格样式实现全选反选...

Topic 1 : 检测用户的输入 : 题目要求: 编写一个用户注册页面 检测用户名是否是6位以下,密码是否是8位以上,如果不满足要求高亮显示文本框 ; 代码如下 :用户注册页面 .bg {background-color: red; } //编写…

html语言文本框怎么做,HTML文本框参考样式

在网页设计中,常常要使用html文本框来收集一些用户信息或是制作登录页,虽然只是简单的输入框,但是如果加入一些美化设计会使你的页面看起来更加有吸引力,下面就给大家提供了一些html文本框的参考样式和常见的html操作技巧,希望对你的网页制作有帮助。首先我们先看看一个最…

vue改造textarea多行文本框样式

代码如下&#xff08;有注释&#xff09;,因为这个是h5&#xff0c;如果需要pc端的&#xff0c;自行把rem乘100转换成px <template> <div class"contain"><textarea v-model"textareaSeason"placeholder"请输入具体原因"class&q…

html input文本框样式,css设置input文本框样式代码实例_html/css_WEB-ITnose

css设置input文本框样式代码实例: 使用css设置input元素的样式是最为常用的操作之一&#xff0c;当然也是最为基础的操作&#xff0c;可能对于刚刚接触css的朋友还不够熟悉&#xff0c;下面就通过一段简单的代码历史演示一下如何设置文本框的样式&#xff0c;当然这个演示可能并…