深入理解Linux线程(LWP):概念、结构与实现机制(1)

                                               🎬慕斯主页修仙—别有洞天

                                              ♈️今日夜电波:会いたい—Naomile

                                                                1:12━━━━━━️💟──────── 4:59
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


 

目录

Linux线程的概念

定义

从进程理解线程

Linux线程的理解

局部性原理

概念

线程切换为什么效率高?


Linux线程的概念

定义

        课本上的定义:线程是比进程更轻量化的一种执行流,线程是在进程内部执行的一种执行流。大白话:线程是CPU调度的基本单位,进程是承担系统资源的基本实体。

        对于Linux线程详细的定义:在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流 。

 

从进程理解线程

        我们都知道Linux中的一个进程是由对应的PCB、进程地址空间、页表组成的。

        大致的图示如下:

        从上面进程的大致示意图可见,如果我们要创建一个进程,还是挺麻烦的,它要创建对应的PCB来管理,要加载各种各样的数据,涉及到IO等等。可以发现成本是挺高的。进程在创建时需要做很多工作。而线程就是在进程创建完成后,只需再创建“PCB”指向该进程的地址空间,再将代码数据等等拆解成几部分,分别让这些“PCB”进行管理对应的部分,他无需再进行资源的申请等等操作,只需进行资源的分配即可。CPU在识别到这些“PCB”时,他就会执行该进程的一部分代码、一部分数据,我们把这种比传统的进程更轻的概念叫做“线程”。当然,由于线程访问的是同一块地址空间,那么他们是很容易实现某一部分代码、数据的共享的。

        而如果OS如果要支持线程,那么也是需要管理线程的,那么就需要按照六字真言:“先描述,在组织”来进行管理。对此OS中有两种管理线程的方法:方法一:按照像上述进程一样创建PCB,额外的像进程一样创建名为:TCB(Thread Control Block)来描述,再像进程一样创建调度队列、阻塞队列、运行队列、优先级等等等等。还需要对应的数据结构、算法等等来维护起来方法二:从方法一可以知道线程所需的属性跟进程是很相似的,我们可以“拿PCB来充当TCB”,可以直接复用进程的管理方法来管理线程。在Linux中,我们就是使用方法二来管理线程的,很明显方法二更简单,更加可靠,健壮性更,更好维护。Linux中线程也叫做:轻量级进程(LWP)(light weight process)大致图示如下:

        从上图可知,Linux中其实不存在实际意义上的线程,他只是利用进程的数据结构来模拟了线程,所以CPU在调度时,他不管进程还是线程,他看到一个PCB就会执行对应的方法,他们都可以被称为“轻量级进程”。因此,上面对应的线程的执行流<=进程的执行流。

Linux线程的理解

        通过代码来理解Linux线程(对于下面的一些线程相关函数后续详细介绍):

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

int gcnt = 100;

// 新线程
void *ThreadRoutine(void *arg)
{
    const char *threadname = (const char *)arg;
    while (true)
    {
        std::cout << "I am a new thread: " << threadname << ", pid: " << getpid() << "gcnt: " << gcnt << " &gcnt: " << &gcnt << std::endl;
        gcnt--;
        sleep(1);
    }
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, ThreadRoutine, (void *)"thread 1");//创建进程
    while (true)
    {
        std::cout << "I am main thread"
                  << ", pid: " << getpid()  << "gcnt: " << gcnt << " &gcnt: " << &gcnt << std::endl;
        sleep(1);
    }
    return 0;
}

        如下图可知:我们创建了一个线程,在创建线程后,可以很明显的看到我们共享了全局变量。对于创建了一个线程前,我们可以理解为原来只有一个线程(也就是进程)。后来创建了一个线程后,我们就拥有了两个线程,通过传入对应的函数即可区分两个进程,他们还可以共享同一段代码(全局变量)

        我们可以通过以下代码查看线程:

ps -aL 

局部性原理

概念

        局部性原理是指在程序执行期间,无论是指令还是数据的访问都倾向于聚集在一个较小的连续区域中。它主要分为两种类型:

  • 时间局部性:如果一个指令或数据刚刚被访问过,那么它将很可能在不久的将来再次被访问。这种现象是由于程序中存在循环和迭代等结构,导致相同的指令或数据被重复使用。
  • 空间局部性:如果一个指令或数据被访问,那么与其相邻的指令或数据也很可能即将被访问。这是因为程序往往是顺序执行的,指令和数据在内存中的位置通常是连续的,因此访问也是连续的。

        局部性原理是计算机体系结构中的一个重要概念,它直接影响了CPU缓存的设计和操作系统的内存管理策略。了解和利用局部性原理,可以帮助开发者编写更高效的程序,同时也指导硬件设计者优化处理器性能。

线程切换为什么效率高?

        CUP中存在着一个硬件叫做cache,他通常用于用于存储最近访问的数据和指令以提高计算机性能

        局部性原理给预加载机制提供了理论基础,预加载机制可以将一部分代码预先加载到缓冲区里,如果CPU正在访问第10行代码,以后很大概率会访问附近的代码,所以一旦访问到第10行就会把10行附近的数据和代码全部加载到内存中或者CPU的cache中。保存在cache中的数据叫做热数据。cache在缓存时是以线程为单位的,线程间切换不需要切换cache,因为他们同属于一个进程,而进程间切换需要切换cache,重新预加载。为什么线程切换为什么比进程高?因为:1、寄存器少。2、不需要重新更新cache。

 


                       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                        给个三连再走嘛~  

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

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

相关文章

【rust】10 project、crate、mod、pub、use、项目目录层级组织、概念和实战

文章目录 一、项目目录层级组织概念1.1 cargo new 创建同名 的 Project 和 crate1.2 多 crate 的 package1.3 mod 模块1.3.1 创建嵌套 mod1.3.2 mod 树1.3.3 用路径引用 mod1.3.3.1 使用绝对还是相对? 1.3.4 代码可见性1.3.4.1 pub 关键字1.3.4.2 用 super 引用 mod1.3.4.3 用…

内衣洗衣机什么牌子好又便宜?实力非凡机型深度测评

内衣裤这种小件的衣物紧密接触皮肤&#xff0c;更是接触特殊生理部位&#xff0c;所以&#xff0c;内衣裤对卫生标准有着特殊要求&#xff0c;现在很多人都是&#xff0c;把内衣裤放到家里的大型洗衣机和其他衣物混洗&#xff0c;你应该知道大型洗衣机由于长期清洗一些大件的衣…

1.2 debug的六种指令的使用,四个通用寄存器

汇编语言 首先进入环境 mount c d:masm //把c挂载在d盘中的masm当中 c: //进入c&#xff0c;进入到编译环境 dir //查看文件&#xff0c;可有可无Debug是DOS、Windows都提供的实模式&#xff08;8086 方式&#xff09;程序的调试工具。使用它可以查看CPU各种寄存器中的内容…

Find My运动相机|苹果Find My技术与相机结合,智能防丢,全球定位

运动相机设计用于在各种运动和极限环境中使用&#xff0c;如徒步、登山、攀岩、骑行、滑翔、滑雪、游泳和潜水等&#xff0c;它们通常具有防抖防震、深度防水和高清画质的特点&#xff0c;能够适应颠簸剧烈的环境&#xff0c;甚至可以承受一定程度的摔落&#xff0c;一些运动相…

Go开发 入门以VSCode为例

一、Go环境搭建 1.1 安装 进入Golang官网 https://go.dev&#xff0c;点击 Download 若无法打开网页可以使用国内的Go语言中文网 https://studygolang.com/dl 进入下载 找到合适的平台点击链接下载即可&#xff08;这里以Windows距离&#xff09; 下载完成后 Next Next 安…

rabbitmq重编辑版本

消息队列RabbitMQ详细使用 文章目录 消息队列RabbitMQ详细使用MQ 的相关概念什么是MQ为什么要用MQMQ 的分类MQ 的选择 RabbitMQRabbitMQ 的概念四大核心概念各个名词介绍安装RabbitMQWeb管理界面及授权操作Docker 安装Hello world简单示例 Work Queues轮训分发消息消息应答自动…

【数据分享】2001-2022年我国省市县镇四级的逐日平均降水量数据(免费获取\excel\shp格式)

降水数据是我们在各项研究中最常用的气象指标之一&#xff01;之前我们给大家分享过来源于国家青藏高原科学数据中心发布的1961—2022年全国范围的逐日降水栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01; 本次我们分享的是2001-2002年我国省市县镇四个…

基础!!!吴恩达deeplearning.ai:卷积层

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 文章目录 回顾——密集层 Dense Layer卷积层 Convolutional Neural Network定义优势具体说明心电图卷积层搭建 到目前为止&#xff0c;你使用的所有神经网络层都是密集层类型&#xff0c;这…

瑞_23种设计模式_组合模式

文章目录 1 组合模式&#xff08;Composite Pattern&#xff09;1.1 介绍1.2 概述1.3 组合模式的结构1.4 组合模式的分类1.5 组合模式的优点1.6 组合模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 &#x1f64a; 前言&#xff1a;本文章为瑞_系列…

AI大模型-启航

文章目录 什么是大模型&#xff1f;&#xff08;大体现在参数量巨大&#xff09;大模型将会改变那些行业&#xff08;大模型有哪些作用&#xff1f;&#xff09;如何搞数据训练模型&#xff1f;LangChain带来的技术变革LangChain架构 什么是大模型&#xff1f;&#xff08;大体…

网络编程作业day2

1.将TPC和UDP通信模型各敲两遍 &#xff08;1&#xff09;TPC通信模型&#xff1a; 服务器代码&#xff1a; #include <myhead.h> #define SERVER_IP "192.168.125.136" #define SERVER_PORT 1314 int main(int argc, const char *argv[]) {//1、创建用于监…

信号系统之滤波器比较

比较 1&#xff1a;模拟与数字滤波器 大多数数字信号源自模拟电子设备。**如果需要对信号进行滤波&#xff0c;是在数字化之前使用模拟滤波器&#xff0c;还是在数字化后使用数字滤波器更好&#xff1f;**将通过两个对比来回答问题。 目标是提供 1 kHz的低通滤波器。模拟端是…

八股文打卡day24——数据库(1)

面试题&#xff1a;左连接和右连接的区别&#xff1f; 我的回答&#xff1a; 左连接的SQL语句是&#xff1a;左表 left join 右表 on 连接条件&#xff0c;表示以左表为基础&#xff0c;将左表的的所有记录与右表进行连接。即使右表中没有与左表匹配的记录&#xff0c;左连接…

ROS 2基础概念#2:节点(Node)| ROS 2学习笔记

ROS 2节点简介 节点是执行计算的进程。节点组合在一起形成一个图&#xff08;graph&#xff09;&#xff0c;并使用主题&#xff08;topic&#xff09;、服务&#xff08;service&#xff09;和参数服务器&#xff08;paramter server&#xff09;相互通信。这些节点旨在以细粒…

力扣-H指数

问题 给你一个整数数组 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义&#xff1a;h 代表“高引用次数” &#xff0c;一名科研人员的 h 指数 是指他&#xff08;她&#xff09…

Tomcat服务部署

1、安装jdk、设置环境变量并测试 第一步&#xff1a;安装jdk 在部署 Tomcat 之前必须安装好 jdk&#xff0c;因为 jdk 是 Tomcat 运行的必要环境。 1. #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02. #将安装 Tomcat 所需软件包传到/opt…

数据结构与算法 - 数组与二分查找 + Leetcode典型题

1. 什么是数组 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 C中二维数组在地址空间上也是连续的。 需注意&#xff1a; 数组的下标从0开始。数组内存空间的地址是连续的。数组的元素是不能删的&#xff0c…

c#打印BarTend标签提示:具名数据源没有cuckoo*具名数据(解决)

c#打印BarTend标签提示&#xff1a;具名数据源没有cuckoo*具名数据&#xff08;解决&#xff09; 今天咕咕更新打印模板的时候遇到的问题&#xff0c;就是在模版中配置了字段名&#xff0c;但是启动c#应用&#xff0c;后端发送json数据打印的时候c#报错提示&#xff0c;没有在…

ywtool ssh命令

一.SSH免密登陆介绍 这个功能就是通过脚本对本机器和其他机器配置SSH密钥&#xff0c;并将自己的密钥放到其他机器上(确保运维的机器要安全)&#xff0c;这样可以不用输入密码就能登陆&#xff1b;通过scp拷贝文件也不需要输入密码。此功能也可以设置机器root用户只用密钥登陆…

【办公类-22-07】周计划系列(3-2)“信息窗+主题知识(优化)” (2024年调整版本)

作品展示&#xff1a; 背景需求 前文对“2023年2月”的一套信息窗主题知识的文件系列&#xff0c;进行第一次的提取。获得基础模板。 【办公类-22-07】周计划系列&#xff08;3-1&#xff09;“信息窗主题知识&#xff08;提取&#xff09;” &#xff08;2024年调整版本&…