【Linux线程篇】探索Linux多线程:并行编程的入门指南

W...Y的主页 😊

代码仓库分享💕 

 Linux线程概念

什么是线程

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

在Linux系统下,线程与进程的最终目的都是一样的,都是想要让程序并发执行,所以我们可以将代码进行分块执行,所以就要创建自己的tcb结构体来维护自己的上下文、优先级等等。但是Linux设计者认为pcb与tcb具有极度的相似性没必要设计单独设计数据结构和算法,直接复用既可,所以Linux中的线程也被称为“轻量化进程”!!!

所以进程是一个或多个执行流加页表加地址空间加代码和数据。进程在内核角度为承担分配系统资源的实体!!!

那多个执行流是怎么划分代码呢?
我们经常说申请内存和释放内存,所以我们应该对内存做管理,其实物理内存也会被划分为4kb(大部分划分规则)的数据块,而磁盘中的数据块也是4kb的,他们被我们称为页框或页帧。当我们内存与数据块的交互时就是以数据块为单位的交互。操作系统要管理内存,肯定要先描述再组织,所以内存有属于自己的结构体struct page,其结构体的内容也应该是记录一个数据块的状态,使用者是谁,是否被使用,是否可以交换等等。假如我们物理内存为4GB,其就有1048576个4kb数据块,我们就可以创建一个是结构体数组进行存储结构体内容。

其源码一部分:

所以我们的页表也不可能是所谓的kv关系,因为kv分别代表一个指针,再加上其对应权限可能有10个字节,但是如果是一一对应的关系其页表可能会有40GB大小,所以页表是怎么映射的呢?虚拟地址是32位二进制,划分为三个部分10位10位12位,其第一个10位被称为页目录,需要创建2^10个格子,第二个10位被称为页表,页目录保存的是二级页表的地址,所以页表应该有1024个,每个页表中有1024个页表项,每一个页表项中存放的是4kb内存块的起始地址(也就是页框的物理地址)。而我们的后12位的大小为4kb,所以我们又知道其对应的起始地址,所以我们对应的起始物理地址+后12位偏移量就是最终所访问的数据。所以我们的后12位被称为页内偏移。

我们也可以再页表中加上标志位,让CPU与页表中的标志位进行比对,如果相同就可以访问物理内存的内容。 

所以给不同的线程分配不同的区域,本质就是让不同的线程各自看到全部页表的子集。

那是怎么才能看到不同的页表呢?这里我们得转到应用层面来看,所以让我们先了解一些系统调用函数:

第一个参数线程id,第二个参数线程属性,第三个参数是返回值void*参数也是void*的函数指针,第四个参数是我们给第三个函数指针所指向的函数所传递的参数。

一般情况下我们的第二个参数可以写nullptr。

注意:在我们使用pthread库中函数时,在编译时必须链接上pthread库!!!

这样我们就可以简短写一个代码:

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>void *newthreadrun(void *args)
{while (true){std::cout << "I am new thread, pid: " << getpid() << std::endl;sleep(1);}
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, newthreadrun, nullptr);while (true){std::cout << "I am main thread, pid: " << getpid() << std::endl;sleep(1);}
}

这时我们的代码就有两个执行流,我们从main函数开始运行,当走到pthread_create函数时新线程创建成功会进入newthreadrun函数中去,主线程继续往下执行即可。

 在这里我们只能看到一个进程,我们可以使用ps -aL查看轻量级进程就可以看到两个进程了。

主线程的PID==LWP,但是其线程所有的PID都是相同的。所以我们在回归到上述问题上每一句代码都有其对应的虚拟地址,主线程拥有的是主函数的虚拟地址其余线程得到的是其他函数的虚拟地址,对应其页表就可以访问到不同的数据。 

所谓的Linux就根本没有线程这个说法,只有轻量化进程,所以对应的Linux内核就没有对线程的系统调用只有对轻量化进程的系统调用。而用户只知道线程不知道轻量化进程,所以设计者在用户和内核之间设计一个软件层pthread库——原生线程库。这个库的作用就是将Linux的轻量级进程系统调用进行封装,转化成线程相关接口提供给用户。

轻量级进程也有直接的系统调用,但是太复杂一般没有人想用!!! 


以上就是本次全部内容,感谢大家观看! 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

揭秘:离心风机风量背后的科学原理

在工业生产和建筑环境中&#xff0c;离心风机如同一位不倦的呼吸管家&#xff0c;默默地维持着空气流动与品质。 你是否好奇过&#xff0c;究竟是什么因素在背后操纵着这位“呼吸管家”的风量表现呢&#xff1f;今天&#xff0c;就让我们一探究竟。 举个例子&#xff1a;你在吹…

『大模型笔记』GraphRAG:利用复杂信息进行发现的新方法!

GraphRAG:利用复杂信息进行发现的新方法! 文章目录 一. GraphRAG:利用复杂信息进行发现的新方法!1. 将RAG应用于私人数据集2. 整个数据集的推理3. 创建LLM生成的知识图谱4. 结果指标5. 下一步二. 参考文献微软官方推文:https://www.microsoft.com/en-us/research/blog/gra…

HTML5文本标签、图像标签、超链接

一、文本样式标签 字体样式标签&#xff1a; 加粗&#xff1a;<strong>…</strong> 斜体&#xff1a; < em >…</ em> eg&#xff1a; <h3>徐志摩人物简介</h3> <p> <strong>1910</strong>年入杭州学堂<br/> &l…

微信小程序 - 本地存储 增加有效期

小程序的本地存储API提供了wx.setStorageSync和wx.setStorage来存储数据&#xff0c;注意的是&#xff0c;小程序的本地存储并没有明确的有效期设置&#xff0c;存储的数据在不超过限制的情况下&#xff0c;会一直保留。 一、小程序本地存储API 小程序的本地存储API提供了设置…

WEB06JavaScriptAjax

基础语法 引入方式 引入方式 内部脚本&#xff1a;将JS代码定义在HTML页面中 JavaScript代码必须位于<script></script>标签之间 在HTML文档中&#xff0c;可以在任意地方&#xff0c;放置任意数量的<script> 一般会把脚本置于<body>元素的底部&a…

常见的气体流量计有哪些?

1.气体涡轮流量计 适用场合&#xff1a;流量变化小&#xff0c;脉动流频率小&#xff0c;中低压洁净天然气优点 1.精度高&#xff0c;重复性好 2.测量范围广&#xff0c;压损小&#xff0c;安装维修方便 3.具有较高的抗电磁干扰和抗震动能力缺点&#xff1a;分辨率低&#xff…

浏览器中js外挂脚本的执行方式

1、开发工具控制台交互执行 网页中按F12打开开发者工具&#xff0c;选择“控制台”&#xff0c;键入js脚本命令回车执行&#xff0c;适用于临时使用脚本逻辑简单的场景&#xff0c;实例如下&#xff1a; // 获取网页元素的文本脚本 var elem document.getElementById("…

接入应用内支付服务,提高商业变现效率

在当今竞争激烈的移动应用市场中&#xff0c;开发者们面临着提升应用商业变现能力的挑战。用户体验的流畅性和支付的安全性至关重要。 HarmonyOS SDK应用内支付服务&#xff08;IAP Kit&#xff09;为开发者提供了一站式的解决方案&#xff0c;简化了应用内支付的接入流程&…

C嘎嘎:类和对象(一)

目录 面向过程和面向对象的初步认识 类的引入 类的定义 类的访问限定符及封装 访问限定符 封装 类的作用域 类的实例化 类对象模型 如何计算类对象大小 结构体内存对齐规则 this指针 this指针的引出 this指针的特性 类的6个默认成员函数 构造函数 概念 特性 …

喜讯丨美格智能通过国际EcoVadis平台认证企业社会责任并荣获承诺奖章,彰显可持续发展实力

作为全球领先的无线通信模组及解决方案提供商&#xff0c;美格智能在社会责任领域再创新高。近日&#xff0c;美格智能凭借在企业社会责任和可持续性采购发展方面的卓越表现&#xff0c;通过国际在线权威评价机构EcoVadis对公司环境、劳工与人权、商业道德、可持续采购等方面审…

根据空格、制表符、回车符等分割字符串re.split

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 根据空格、制表符、 回车符等分割字符串 re.split [太阳]选择题 根据给定的Python代码&#xff0c;哪个选项是正确的&#xff1f; import re pattern r\s print(f"【显示】pattern{…

高清图片压缩无水印小程序源码系统 前后端分离 带完整的安装代码包以及搭建教程

系统概述 在当今的数字化时代&#xff0c;图片作为信息传播的重要载体&#xff0c;其质量和传输效率直接影响到用户体验。然而&#xff0c;高清图片往往伴随着较大的文件体积&#xff0c;这不仅会占用大量存储空间&#xff0c;还会拖慢网页或应用的加载速度。因此&#xff0c;…

热烈祝贺!全视通多家客户上榜全球自然指数TOP100!

2024年6月18日&#xff0c;全球医疗机构自然指数TOP100榜单发布&#xff0c;中国医疗机构在其中的表现尤为引人注目。 根据《自然》杂志网站发布的数据&#xff0c;此次公布的排名是基于&#xff08;2023年3月1日至2024年2月29日&#xff09;的统计数据&#xff0c;全球医疗机构…

旗晟机器人AI智能算法有哪些?

在当今迅猛发展的工业4.0时代&#xff0c;智能制造和自动化运维已然成为工业发展至关重要的核心驱动力。伴随技术的持续进步&#xff0c;工业场景中的运维巡检已不再单纯地依赖于传统的人工运维方式&#xff0c;而是愈发多地融入了智能化的元素&#xff0c;其中智能巡检运维系统…

前端Din字体和造字工房力黑字体文件

Din 字体是一种经典的、简洁的无衬线字体&#xff0c;它源自1930年代的德国交通标志设计。 造字工房力黑字体适用于数字&#xff0c;驾驶舱标题等统计界面 DIN-Medium.otf 案例 造字工房力黑.TTF 案例

记录一次MySql锁等待 (Lock wait timeout exceeded)异常

[TOC](记录一次MySql锁等待 (Lock wait timeout exceeded)异常) Java执行一个SQL查询未提交&#xff0c;遇到1205错误。 java.lang.Exception: ### Error updating database. Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transactionCluster…

动手学深度学习6.2 图像卷积-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;卷积层_哔哩哔哩_bilibili 代码_哔哩哔哩_bilibili 本节教材地址&#xff1a;6.2. 图像卷积 — 动…

浅析Nginx技术:开源高性能Web服务器与反向代理

什么是Nginx&#xff1f; Nginx是一款轻量级、高性能的HTTP和反向代理服务器&#xff0c;也可以用作邮件代理服务器。它最初由俄罗斯的程序员Igor Sysoev在2004年开发&#xff0c;并于2004年首次公开发布。Nginx的主要优势在于其非阻塞的事件驱动架构&#xff0c;能够处理大量并…

Vue3使用ref绑定组件获取valueRef.value为null的解决

问题&#xff1a; onMounted(() > {nextTick(()>{console.log(treeselectRef, treeselectRef.value);console.log(treeselectRef.value, treeselectRef.value);}); });输出&#xff1a; 查看绑定和定义都没有问题&#xff0c;还是获取不到 解决&#xff1a;使用getCur…

14-55 剑和诗人29 - RoSA:一种新的 PEFT 方法

介绍 参数高效微调 (PEFT) 方法已成为 NLP 领域研究的热门领域。随着语言模型不断扩展到前所未有的规模&#xff0c;在下游任务中微调所有参数的成本变得非常高昂。PEFT 方法通过将微调限制在一小部分参数上来提供解决方案&#xff0c;从而以极低的计算成本在自然语言理解任务上…