【Linux】多线程概念再理解

简介: 【Linux】多线程概念再理解

1. 物理内存与磁盘的关系

如何理解物理内存?

物理内存的宽度为1字节

如使用c语言,可以定义出char类型(1字节),在虚拟地址空间上可以把1字节的单位映射到内存中

如果认为内存是按照字节为单位去划分的,实际上是不正确的

4632c79ce5b240b7a97602806b7498e8.png

把数据从磁盘换入物理内存,把数据从物理内存换入磁盘,是一个高频的工作,物理磁盘是一个机械设备,作为外设

整体会很常慢,使整机的效率低下,若过多进行IO,就导致过多的寻址操作,即 效率低下

当有100MB的空间写到磁盘中,1次写入到磁盘中,还是分100次写入,每次写入1MB的数据 那个效率高?

1次写入到磁盘中肯定是更高,因为只需要一次寻址操作

说明OS和磁盘进行IO交互时,绝对不是按照字节为单位的,而是要按照 块(4KB) 为单位

若只想修改一个比特位,也必须IO4KB,因为 4KB 作为一个块 是一个整体

若要把文件加载到内存,以4KB为单位,需要在两个方面下考虑


1.文件系统 +编译器

若要从外设磁盘中读取4KB,前提是文件系统认4KB,文件本身按照4KB进行存储

所以文件在磁盘时,就以块为单位的4KB

文件也包括可执行程序和动态库,也是需要存到磁盘上的,都要按照4KB为单位储存到磁盘上


2.操作系统+内存

当磁盘按照4KB的方式把数据存好, 物理内存也要提供保存4KB的数据空间


02182d9ec704454885c1ae54b23b5cbc.png

把物理内存中存放数据的空间称之为 页框

磁盘中数据块称之为 页帧

内存在实际进行内存管理的时候,也要是4KB为单位的

内存管理的本质:将磁盘中特定的4KB块(数据内容)放入到哪一个物理内存的4KB空间(数据保存的空间)

凭什么物理内存要分为一个个4KB大小?

操作系统要管理这些配置

而管理的本质是先描述,在组织

先描述

内核中,有对应的配置数据结构struct page 来管理对应的配置

struct page 是一个结构体,包含这个配置的状态

再组织

通过数组的方式来进行管理

2d729f607a324d6fb47f669e045b2d05.png

数组有下标存在,物理内存中分别对块进行编号0-n ,

若想要在查询物理内存中那些位置被占用,通过找到对应数组下标,即可看到对应的结构体里面对应的状态

若没有分配,则将状态置为1

若以块方式存储,则多出的空间是否浪费?

假设访问一段代码只有10个字节,load时以4KB为块进入磁盘中,则会多出来2KB的空间


局部性原理的特性, 允许提前加载正在访问数据的相邻或者附近的数据


通过预先加载要访问数据的附近的数据来减少未来的IO次数

多加载进来的数据,本质就是 数据的预加载


如果还不懂,则点击查看:局部性原理详细解释

2. 虚拟地址到物理地址的转换

一个虚拟地址对应32个比特位

虚拟地址不是被整体使用的,被划分 10 +10 +12


e5295517d8244cc7aca796996a736d90.png

当前页表需要2^10行

根据前10个比特位的二进制序列,找到页表1所对应的位置


ea7efcc114494278b5d338acf2fb77aa.png


页表1的左侧代表 前10个比特位,右侧代表另一个页表的起始地址

根据 第二个 10个比特位,找到页表2对应的位置

页表2的左侧代表 第二个 10个比特位 , 右侧代表物理地址(页框的起始地址)

对应页框的起始地址+ 虚拟地址的低12个比特位对应的地址数据 本质为 页内偏移


定位到页框内的任意地址


3. 缺页中断

申请物理内存后,不一定立马用,若立马申请物理内存,不用就导致内存一直被占着,处于闲置的状态,不是高效的表现

实际申请malloc内存时,操作系统只要给你在虚拟地址空间上申请就行了,当真正访问时,操作系统会自动申请或者填充页表以及申请具体物理内存


71ad5b42ce5c44e3ac46495ff896641a.png


MMU查询页表找不到,但确实空间已经申请了,就会触发缺页中断,

OS会执行对用的处理方法 即申请物理内存用于填充页表,再返回继续执行代码

4. 为什么字符常量区是不允许被修改的?

deddddf334e34e798743baaf354d626d.png

hello world在常量区,只能被读取,不能被修改,所以*s=‘w’,是错误的


s里面保存的是指向的字符的虚拟起始地址

*s寻址时,会伴随虚拟地址到物理地址的转换


通过查页表的方式,对操作进行权限查询,发现只有读的权限,但没有修改的权限,所以MMU(内存管理单元)异常,

OS识别到异常,给目标进程发送信号 即 在内核态转换为用户态时,进行信号处理—终止进程

5. 线程缺点

1. 性能损失

创建过多的线程,只有少数在运行,大多数的线程来回被调度 造成性能损失 即多线程创建不合理

2.健壮性降低

如果一个线程出现问题,可能会对整个进程造成影响

3.缺乏访问控制

每个执行流通过同一个地址空间看到的资源是相同的

对于健壮性降低的验证

46d3d77225d644e68e40e26138224c41.png

共有三个死循环,若只有一个执行流,三个死循环不可能执行

若都执行了一定有三个执行流


a66115d84cb24a5392d2000a0f37d73a.png


说明有三个执行流


95a96222d33744dcae24f8d00d5dfe94.png


LWP称为轻量级进程 即线程

每个线程的PID相同,说明属于同一个进程

PID与LWP相同,说明是主线程


730e907324f44261807508b4a9e7fd15.png


在线程2中设置非法操作,使线程崩溃


d2b72523eebd4b9f80ad5ea0afd639e7.png


运行时会发生段错误, 刚开始线程是可以运行的,但是发生段错误后,进程崩溃了


在多线程程序中,任何一个线程崩溃了,最终都会导致进程崩溃

缺乏访问控制的验证

524fb0afe78041e8a8e624495d9b030a.png

定义一个全局变量,线程1和主线程把全局变量的地址和全局变量的数据打印出来

线程2把全局变量的地址和数据的同时,把数据++


5d00a76485f94d748885538b2dec1aef.png

当有一个线程中的数据修改后,所有的线程中的数据都跟着修改

以全局变量为例,在多线程场景中,多个线程看到的是同一个全局变量


相关文章
|
1月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
1月前
|
算法 Unix Linux
linux线程调度策略
linux线程调度策略
40 0
|
29天前
|
存储 缓存 Linux
在Linux中,文件系统概念是什么?
在Linux中,文件系统概念是什么?
|
1月前
|
存储 设计模式 NoSQL
Linux线程详解
Linux线程详解
|
1月前
|
缓存 前端开发 JavaScript
一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
【8月更文挑战第11天】一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
27 0
一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
|
1月前
|
Linux Shell 调度
【在Linux世界中追寻伟大的One Piece】Linux进程概念
【在Linux世界中追寻伟大的One Piece】Linux进程概念
24 1
|
29天前
|
存储 安全 Linux
在Linux中,用户和组的概念是什么?
在Linux中,用户和组的概念是什么?
|
29天前
|
Linux 持续交付 虚拟化
在Linux中,Docker和容器虚拟概念是什么?
在Linux中,Docker和容器虚拟概念是什么?
|
1月前
|
负载均衡 Linux 调度
在Linux中,进程和线程有何作用?
在Linux中,进程和线程有何作用?
|
1月前
|
安全 Linux 调度
在Linux中, 用户和组的概念是什么?作用分别是什么?
在Linux中, 用户和组的概念是什么?作用分别是什么?