文章目录
🚩理解Linux中线程
实际上,可以多个PCB对应同一个地址空间,每个PCB分配一部分地址空间,每个PCB加上部分地址空间就是线程,
⭐线程:是进程的一个执行分支,线程的执行粒度要比进程要细,
怎么理解之前的进程?
之前的进程就是单线程,也是主线程,

这是之前的进程,
操作系统以进程为单位为我们分配资源,但是进程内部只有一个执行流

实际上,多个线程加上地址空间加页表加一部分物理内存,这才是进程
CPU会理解主线程还是其他线程吗?
🚩不会,CPU只认识执行流,Linux中执行流是轻量级进程,即线程<=执行流<=进程
🚩重新定义线程进程
线程:操作系统调度的基本单位
进程:操作系统分配资源的基本实体,线程是进程内部的执行流资源
重谈地址空间
🚩页表结构

CPU中CR3寄存器会存储页表地址,CPU也会访问PCB拿到内核区中的页表地址,CPU访问的是虚拟地址
虚拟地址到物理地址怎么转换的?
32位电脑为例,一共有2^32位地址,
页表对应地址,4字节虚拟地址,4字节物理内存,假如又有2字节权限位,10字节*4GB,整个物理内存都装不下,所以肯定不是一一对应关系
物理内存4GB,一个页框4KB,一共有2^20个页框,
🚩 页表32位被拆成 10+10+12,前10位对应一个页表,中间10位对应一个页表,形成2级页表,第一级页表(也叫页目录)指向第二级页表,第二级页表存储物理页框号,后12位到相应页框偏移,找到物理地址,2级页表正好包括了2^20个页框,
🚩注意:
- 第二级页表通常填不满,因为操作系统不可能把物理内存全用完,所以第二级页表很多不分配
- 虚拟地址后12位页表不存储,因为12位都是一样的,不需要额外占用空间了,CPU可以直接提取虚拟地址低12位用,所以第二级页表只需存储20位但是后面几位是标识位,就是权限等等
页表大小:
每个页目录项指向第二级页表加上标识位,4字节,1024*4=4KB,
同理,第二级页表项也是4字节,1024*4=4KB,
🚩所以:整个页表系统 = 1个页目录 + N个第二级页表
(4KB) + (N × 4KB)
最多4MB,况且肯定用不到这么多
一个第二级页表可以映射1024*4KB=4MB虚拟内存
🚩这么麻烦,而且页表也不小,所以创建进程是一个很重的事

另外:
C/C++任何一个类型取地址取的都是一个最小地址,那我们int不是4个字节?int就是偏移量,我们向上找4个字节就行,起始地址+类型=起始地址+偏移量

线程进程切换
🚩为什么线程比进程要轻量化? 对线程整个周期来说:
- 创建和释放更加轻量化(生死),像上面进程创建很麻烦,而线程创建只需要共享地址空间页表等资源就行(还要分配自己的栈空间),
- 切换更加轻量化(运行)
为什么切换更轻量化?
CPU有硬件单元cache运行时会缓存上下文数据,cache的数据被称为热数据,也就是CPU运行太快,觉得内存运行还是慢了,于是保存了上下100行地址(假如),所以一个进程运行会越来越快,因为热数据命中率越来越高,但是切换进程时,cache就要切换就要冷却,所以变慢了,但是切换线程就不会,因为属于同一块空间
线程分配空间的本质:就是分配地址空间
线程优缺点
优点
1,创建线程代价比进程小的多
2,操作系统切换线程比进程操作更少
3,线程所占空间更少
4,能充分利用多处理器的可并行数量
5,在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
6,计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
7,I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
缺点
1,性能缺失,如果线程太多,比起单线程来说,频繁切换也要花时间的,多个线程瓜分进程时间片了
🚩2,健壮性缺失。访问失去控制,一个线程出异常,整个进程都会崩溃
3,编写困难,编写多线程比单线程难多了
最后
线程会共享进程的文件描述表,每种函数处理方式,用户id和组id
但是线程也有自己独有数据,是线程独立运行的标志
- 一组寄存器(上下文数据)
- 栈空间