【Linux系统】线程:认识线程、线程与进程统一理解




在这里插入图片描述



一、更新认知


之前的认知

  • 进程:一个执行起来的程序。进程 = 内核数据结构 + 代码和数据
  • 线程:执行流,执行粒度比进程要更细。是进程内部的一个执行分值

更新认识:

  • a. 进程是承担分配系统资源的基本实体
  • b. 线程是OS调度的基本单位


二、Linux下线程的概念和实现


线程是进程内部的一个执行分支,说明一个进程就可能有多个线程,这样OS就必须将线程管理起来,Linux系统管理线程会通过先描述,再组织的方式,先将线程描述成一个结构 struct threadctlblock ,再对该结构进行组织,达到对系统内线程的管理组织。


线程结构也是 task_struct

实际上,在 Linux系统中,没有真正的 struct threadctlblock 的 TCB 结构,Linux下的线程是用进程模拟实现的!


线程也使用进程的 task_struct 来描述,这样就无需为线程单独创建一套线程的管理机制,毕竟线程和进程过于相像,用进程模拟线程,大大减少了操作系统内核设计的难度,复用了历史代码,增加代码可维护性

减少了许多设计工作,如:线程创建、线程队列链表组织…、线程切换、线程….


Linux 这一点设计是非常厉害巧妙的,因为其他一些操作系统如 windows 是真的有线程的,内核代码和管理复杂不少!不像 Linux 的伪线程



进程内多线程共用进程资源

一个进程 task_struct 内部还有多个用于描述线程的 task_struct

进程 task_struct 和线程 task_struct 同属于一个PCB结构,他们共享同一个进程地址空间,共享进程内的资源。

比如划分代码区,各个线程负责执行代码的不同部分:


在这里插入图片描述




三、进程vs线程 概念统一


进一步理解

重新理解进程和线程

进程:task_struct + 地址空间 + 页表 + 代码和数据

线程:可以暂时简单理解为一个task_struct(后续会进行更详细的解释)。


进程由PCB描述,每个进程中可能存在多个这样的控制块,它们共享同一个地址空间,分配给不同的任务使用,这便是我们所说的线程。

所以,线程实际上是一个PCB加上代码和数据(还有一些相关数据结构将在后面讨论)。



单线程 vs 多线程


在之前的学习中,每个进程就是单独的一个执行流,只有一个执行分支。这实际上是内部只有一个线程的单线程结构!

当前我们学习了多线程的概念,可以理解到只有一个执行流的进程,是多进程的特殊情况,即单线程结构

这就将进程和线程的概念统一起来了



进程与资源管理


进程作为系统资源分配的基本实体,当我们创建一个进程时,需要为其准备地址空间、PCB、页表等,这些都需要占用内存并申请系统资源。因此,进程承担了分配系统资源的责任。相反,线程无需单独申请系统资源,因为它们依赖于进程已经准备好的资源。线程更像是一个个执行流,负责拿着进程申请的资源去执行各自的程序段。

因此,线程只需划分并使用需要资源(执行程序段所需的资源),而进程才是需要申请系统资源



CPU视角下的进程与线程


从CPU的角度来看,Linux将执行流统一称为轻量级进程(LWP: Lightweight Process)。一个进程由多个轻量级进程组成。然而,在Linux中并没有真正意义上的线程存在;所谓的线程实际上是通过LWP模拟实现的。

轻量级进程是在 UNIX 系统中的一种进程模型,用于支持多线程编程。LWP 提供了一种比传统进程更轻便的方式来创建和管理并发执行的任务。

在传统的 UNIX 系统中,进程是独立运行的基本单位,每个进程都有自己的地址空间和其他资源。而 LWP 则共享一个进程的地址空间和其他资源,因此它们之间的切换开销较小,更适合于需要大量并发任务的应用场景。

LWP 与线程的关系密切,实际上,LWP 就是线程在操作系统中的实际表示形式之一。在某些操作系统中,如 Solaris,LWP 是线程调度的基础,而在其他操作系统中,如 Linux,LWP 可能被隐藏起来,由操作系统内部使用。

总之,LWP 是一种轻量级的进程模型,旨在提供高效的并发执行能力,适用于需要大量并发任务的应用场景。



通俗理解进程和线程


这个世界是一个巨大的操作系统和资源库,我们每个家庭都是一个个进程,作为承担世界分配资源的基本实体(每个家庭都有一定的租房地、生活空间….等资源),而家庭内的每个人都是一个个线程,每个人都有自己需要做的事:如爷爷奶奶早起公园散步锻炼、爸爸妈妈工作赚钱、你和兄弟姐妹上学学习….

每个人做事的最终目的都是为了家庭,为了提高家庭幸福而努力,即进程内的每个线程做着不同的任务,最终目的都是为了完成进程的整个大任务



认识一下线程:代码创建


我们写一些代码来创建一个线程来见识一下(仅为了了解,暂时还没开始讲代码)


创建线程的函数:


在这里插入图片描述



线程相关函数并不是系统调用,而是有一个单独的线程库,编译含有线程创建等函数的程序需要主动连接线程库,线程库是一种动态库


在这里插入图片描述



编译时加上链接线程库:

g++ -o testpthread testpthread.cc -lpthread

代码如下

#include <iostream>
#include <pthread.h>
#include <unistd.h>

void *run(void *args)
{
    while (true)
    {
        std::cout << "I am new thread" << '\n';
        sleep(1);
    }
}

int main()
{
    // 创建新线程
    pthread_t tid;
    pthread_create(&tid, nullptr, run, (void *)"thread-1");

    // 主线程
    while (true)
    {
        std::cout << "I am main thread" << '\n';
        sleep(1);
    }

    return 0;
}

运行结果如下:运行一个程序,有两个执行流打印语句!


在这里插入图片描述



代码:打印进程 pid

这些执行流(线程)都是同属于一个进程的,打印出来的进程pid都是一样的!

#include <iostream>
#include <pthread.h>
#include <unistd.h>

void *run(void *args)
{
    while (true)
    {
        std::cout << "I am new thread" << '\n';
        std::cout << "pid : " << getpid() << '\n';   
        sleep(1);
    }
}

int main()
{
    std::cout << "pid : " << getpid() << '\n';   
    // 创建新线程
    pthread_t tid;
    pthread_create(&tid, nullptr, run, (void *)"thread-1");

    // 主线程
    while (true)
    {
        std::cout << "I am main thread" << '\n';
        std::cout << "pid : " << getpid() << '\n';   
        sleep(1);
    }

    return 0;
}

在这里插入图片描述




上述内容讲解了 LWP 轻量级进程的概念,下面我们见识一下系统层面运行起来的轻量级进程!

ps axj # 这是查询进程的
ps -aL # 这是查询轻量级进程的

在这里插入图片描述



其中:pid 一样,LWP 不同

在这里插入图片描述

LWP pid 一样 的是主线程


CPU区分线程(LWP),即区分执行流的唯一性是以 LWP 号为基准的

CPU真实调度执行流是用 LWP 号

而我们以前学习的说 CPU 用 pid 作为调度,也没错

之前学到进程都是单执行流单线程的,pid = lwp


因此实际上,进程 task_struct 内部有 pid 和 LWP 两种字段,就是为了兼容 Linux 模拟实现线程的情况


四、分页式存储管理

我们通过这篇博客认识和理解一下分页式存储管理系统:【Linux系统】分页式存储管理-CSDN博客



五、进程划分资源给线程


如何理解?如何做到?



逐步引入

首先被划分的资源肯定有代码区,通过划分代码给不同的线程执行?

其次这些划分有没有必要刻意的划分?

根据之前学过的线程创建:pthread_create(..., ..., run, ...)

线程创建出来就会去执行这个 run 函数,这意味着无论创建出来多少个线程都是会通过这些 run 的函数指针的指引找到并执行对应的函数



真相浮出


这些 run 函数都是有自己在虚拟地址空间中的虚拟地址的,我们没必要刻意的划分虚拟地址空间的代码给不同线程执行,因此当线程创建出来时,就已经根据指令为不同线程提供了对应的函数地址,线程只需根据该地址就能找到自己负责的那部分!

每个函数都是一个代码块部分,只要拥有该函数的虚拟地址,就等同于拥有该函数所有代码指令,即该代码块部分的虚拟地址。执行程序时,每个线程都查询不同部分的页表执行代码,不就完成了逻辑上对代码的划分吗!!


总的来说,CPU调度一个 LWP ,只需给他一个函数的入口地址,CPU就能讲该执行流调度运行起来




六、拓展:如何理解写时拷贝?

可以看这篇博客:【Linux系统】如何理解写时拷贝?一次拷贝4KB不浪费?-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

请求响应(接上篇)

请求 日期参数 需要在前面加上一个注解DateTimeFormat来接收传入的参数的值 Json参数 JSON参数&#xff1a;JSON数据键名与形参对象属性名相同&#xff0c;定义POJO类型形参即可接收参数&#xff0c;需要使用 RequestBody 标识 通过RequestBody将JSON格式的数据封装到实体类…

Linux提权--SUDO提权

​sudo​ 是 Linux 中常用的特权管理工具&#xff0c;允许普通用户以其他用户&#xff08;通常是 root 用户&#xff09;的身份运行命令。如果配置不当&#xff0c;攻击者可能通过滥用 sudo​ 权限来提升自己的权限。 一.常见的 sudo 提权方法&#xff1a; 误配置的 sudo 权限&…

【Elasticsearch】filter聚合

在Elasticsearch中&#xff0c;Filter聚合是一种单桶聚合&#xff0c;用于根据特定的查询条件筛选文档&#xff0c;并对筛选后的文档集合进行进一步的聚合分析。它允许用户在执行聚合操作之前&#xff0c;先过滤出符合某些条件的文档&#xff0c;从而更精确地分析数据。 Filter…

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭版系统 带F9 Colorful一键恢复功能

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭中文版系统 带F9 Colorful一键恢复功能 自动重建COLORFUL RECOVERY功能 带所有随机软件和机型专用驱动 支持机型&#xff1a;隐星P15 TA 24 文件下载&#xff1a;asusoem.cn/745.html 文件格式&#xff1a;ISO 系统版本&…

实时波形与频谱分析———傅立叶变换

实时波形与频谱分析&#xff1a;一个交互式动画演示 在信号处理领域&#xff0c;时域波形和频域频谱是理解信号特性的重要工具。通过时域波形&#xff0c;我们可以直观地观察信号随时间的变化&#xff0c;而频域频谱则揭示了信号中所包含的频率成分及其幅值。为了帮助大家更好…

03链表+栈+队列(D1_链表(D1_基础学习))

目录 一、什么是链表 二、基本操作 三、为什么要使用链表 四、为什么能够在常数时间访问数组元素 数组优点 数组缺点 五、动态数组诞生 链表优点 链表缺点 六、链表、数组和动态数组的对比 七、 链表种类 1. 单向链表 2. 双向链表 3. 循环链表 八、链表衍生 ...…

企业微信开发012_使用WxJava企业微信开发框架_封装第三方应用企业微信开发005_多企业授权实现---企业微信开发014

这里主要说一下如何授权的思路,如何来做,其实非常简单, 如果你有很多企业微信需要授权以后才能使用自己开发的,第三方企业微信功能,那么 首先,在企业列表中,你可以给某个企业去配置,这个企业,他对应的企业微信的,比如, 这个企业的企业id,cropID,当然还可以有,比如企业名称,用…

“AI智能分析综合管理系统:企业管理的智慧中枢

在如今这个快节奏的商业世界里&#xff0c;企业面临的挑战越来越多&#xff0c;数据像潮水一样涌来&#xff0c;管理工作变得愈发复杂。为了应对这些难题&#xff0c;AI智能分析综合管理系统闪亮登场&#xff0c;它就像是企业的智慧中枢&#xff0c;让管理变得轻松又高效。 过去…

蓝桥杯思维训练营(三)

文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析&#xff1a;这个题目的关键就是&#xff0c;按照正常来判断对应位置是否相等&#xff0c;如果不相等&#xff0c;那么就判…

[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法

二叉树 基础知识深度优先遍历递归法迭代法&#xff08;栈&#xff09;144# 二叉树的前序遍历94# 二叉树的中序遍历145# 二叉树的后序遍历 广度优先遍历递归法迭代法&#xff08;队列&#xff09;102# 二叉树的层序遍历107# 二叉树的层序遍历 II199# 二叉树的右视图637# 二叉树的…

Hugging Face GGUF 模型可视化

Hugging Face GGUF 模型可视化 1. Finding GGUF files (检索 GGUF 模型)2. Viewer for metadata & tensors info (可视化 GGUF 模型)References 无知小儿&#xff0c;仙家雄霸天下&#xff0c;依附强者才是唯一的出路。否则天地虽大&#xff0c;也让你们无路可走&#xff0…

基于Coze平台实现抖音链接提取文案转小红书文案的智能体开发全流程解析

文章目录 引言:跨平台内容运营的AI解法实例最终效果1. 平台特性对比与转化需求分析1.1 用户画像与内容风格对比1.2 文案转化核心需求2. Coze平台技术架构解析2.1 Coze核心能力矩阵2.2 关键技术组件选型3. 智能体工作流设计3.1 完整处理流程3.2 关键节点说明4. 核心模块实现详解…

【低功耗 Power 学习专栏 -- Power domian 和 power rail】

文章目录 power rail(followpin) 和 Power domain1. Power Domain2. Power Rail3. Followpin4. Power Stripe5. IR Drop芯片中电源管理设计 举例 power rail(followpin) 和 Power domain followpin 指两部分&#xff0c;一个就是 STD cell 上下的 VDD, VSS。同时&#xff0c;f…

PopupMenuButton组件的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容&#xff0c;本章回中将介绍PopupMenuButton组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧&#xff0c;…

TiDB 分布式数据库多业务资源隔离应用实践

导读 随着 TiDB 在各行业客户中的广泛应用 &#xff0c;特别是在多个业务融合到一套 TiDB 集群中的场景&#xff0c;各企业对集群内多业务隔离的需求日益增加。与此同时&#xff0c;TiDB 在多业务融合场景下的资源隔离方案日趋完善&#xff0c;详情可参考文章 《你需要什么样的…

CommonAPI学习笔记-2

一. 概述 ​ 这篇文章主要是想整理并且分析CommonAPI代码生成工具根据fidl和fdepl配置文件生成出来的代码的结构和作用。 二. fidl ​ 用户根据业务需求在fidl文件中定义业务服务接口的结构以及自定义数据类型&#xff0c;然后使用core生成工具传入fidl文件生成该fidl的核心…

ELK模块封装starter

文章目录 1.combinations-elk-starter1.目录结构2.log4j2-spring.xml 从环境变量读取host和port3.ELKProperties.java 两个属性4.ELKAutoConfiguration.java 启用配置类5.ELKEnvironmentPreparedListener.java 监听器从application.yml中获取属性值6.spring.factories 注册监听…

KNN算法:从思想到实现(附代码)

引言 K最近邻算法&#xff08;K Nearest Neighbors, KNN&#xff09;是一种简单而有效的机器学习算法&#xff0c;用于分类和回归问题。其核心思想基于“近朱者赤&#xff0c;近墨者黑”&#xff0c;即通过测量不同特征值之间的距离来进行分类或预测数值。本文将详细介绍KNN的…

学前端框架之前,你需要先理解 MVC

MVC 软件架构设计模式鼎鼎大名&#xff0c;相信你已经听说过了&#xff0c;但你确定自己已经完全理解到 MVC 的精髓了吗&#xff1f; 如果你是新同学&#xff0c;没听过 MVC&#xff0c;那可以到网上搜一些文章来看看&#xff0c;不过你要有心理准备&#xff0c;那些文章大多都…

第十八章 视图

目录 一、概述 二、语法 2.1. 创建视图 2.2. 查询视图 2.3. 修改视图 2.4. 删除视图 2.5. 示例 三、检查选项 3.1. CASCADED&#xff08;级联&#xff09; 3.2. LOCAL&#xff08;本地&#xff09; 四、视图的更新 五、视图作用 5.1. 简单 5.2. 安全 5.3. 数据独…