Linux多线程基础
摘要:本文围绕操作系统线程与进程的核心概念展开,首先对比进程切换与线程切换在寄存器上下文、页表与 TLB 失效上的开销差异,说明进程切换更慢且开销更大;随后介绍 CPU 密集型与 I/O 密集型两类线程的特点及典型场景,并解释 I/O 阻塞与中断唤醒机制;接着梳理 PID、LWPID、tid 与 pthread_t 的区别及获取方式;最后概述 TCP 相对 UDP 的确认应答与超时重传两大核心机制。
1.线程与进程切换的区别
1.1进程切换时 时cpu来执行切换 而线程的切换依赖寄存器上下文 所以说进程的切换比线程快 但是开销大吗
错误原因:把「寄存器上下文」当成了线程独有的代价,误以为进程切换没有这一份开销,所以得出了颠倒快慢的结论。
我的理解:无论是进程切换还是线程切换,都依赖于寄存器上下文。cpu不能直接执行操作指令,是操作系统OS通过cpu来实现的。而进程在切换的时候,还会有一些额外的开销,因此进程切换慢且开销大
正规说法:进程切换和线程切换都需要保存 CPU 寄存器上下文;任务切换由操作系统内核调度程序在 CPU 上执行完成。进程拥有独立的虚拟地址空间,切换时除寄存器外还要更换页表,造成 TLB 失效,带来额外开销。所以进程切换开销大于线程切换,速度更慢。
TLB失效:
首先清楚TLB是什么:页表用来存储虚拟地址物理地址的映射关系(由mmu管理),但是每次调用页表开销过大,因此在cpu内部有一块高速小缓存,用来每次快速调用映射关系。
TLB失效:要访问的虚拟地址在TLB里面没有映射关系,因此要在页表里面加上其对应的映射关系(这句话错误),再返还给TLB。
页表里面本来就有对应的映射关系,只是没有缓存在TLB中。
2.线程的两种类型
|
CPU密集型 |
多个线程通过CPU来同时执行操作(表达稍有问题) 任务大部分时间占用 CPU 进行运算;多核环境下多线程可并行执行;单核开启多线程不会提速。 |
视频渲染,图像处理,数值计算 |
|
I/O密集型 |
线程在等待其他操作时,并不影响其他线程的功能(文字不够精确) 线程在进行IO操作的时候会阻塞休眠,释放CPU去执行其他线程 |
下载工具,爬虫,文件读写 |
这里怎么理解线程在进行IO操作的时候会阻塞休眠,释放CPU去执行其他线程:
线程在执行I/O操作的时间是CPU时间的上万倍,为了提高效率,当线程执行I/O操作的时候,主动进入阻塞等待的状态(错误,是操作系统强制把线程挂起,进入阻塞状态),释放CPU去执行其他操作,当线程I/O操作完成之后,由硬件发出中断信号,将CPU切换回来。
正确完成表述:线程执行 I/O 操作的耗时是 CPU 运算时间的上万倍。为了提高 CPU 利用率,当线程发起 I/O 系统调用后,操作系统会将线程置为阻塞等待状态,线程释放 CPU,CPU 便可调度执行其他就绪线程。当 I/O 硬件完成任务后,硬件发出中断信号通知操作系统,操作系统唤醒该阻塞线程,等待 CPU 调度回来继续执行。
3.如何区分PID,LWPID,tid
PID:进程id,同一个进程里面的所有线程的PID相同。
获取函数:getpid();
LWPID(内核真正认识的线程编号):是轻量级进程ID,Linux操作系统中没有"线程"的概念,其实线程就是共享地址空间的轻量级进程。LWPID主要用于内核调度。
主线程的LWPID==PID;
获取函数:gettid();
pthread_t(用户态线程 ID,pthread 线程 id):POSIX库给出的线程标识,内核根本不认识。作用域仅限当前的进程内部。由pthread_create()函数带回。
获取函数:pthread_self();
5.TCP的核心机制
对于TCP,其相较于UDP有以下几种核心机制:
-确认应答机制:接收方和发送方在传输数据或者信息之前,都有通过ACK应答来确认双方都具有应答的能力。
-超时重传:如果数据在发送之后规定的时间内没有收到ACK应答,就会重新再传输一次。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)