README
大约 5 分钟
README
【概念】进程 线程 协程
介绍
程序 (Program):用某种语言写的为了完成特定任务的一组指令集合,静态的
进程 (Process):程序一次执行过程。每个进程有不同的内存区域(虚拟内存),有产生、存在、消亡的生命周期
- 系统相关:计算机系统资源的分配单位
- 上下文切换需要保存和恢复
- (都要部分,见下总结)
- 内存管理信息:页表、内存分段信息等
- I/O状态信息:打开的文件描述符、网络连接等
- 系统资源信息:CPU使用时间、内存使用量等
- CPU调度信息:如进程优先级、调度队列等,确保调度策略的一致性
线程 (Thread):进程可细分为线程。可同一时间执行(并发)
- 系统相关:CPU调用的单位
- 上下文切换需要保存和恢复
- (都要部分,见下总结)
- 线程栈
- 线程栈 状态:包括线程的优先级、线程标识符(TID)、线程的状态(运行、就绪、阻塞等)等
- 线程栈帧 特有的同步数据
协程 (Goroutine):又称微线程,纤程、轻量级线程。本质还是一个线程
- 系统相关:无关,纯用户态的
- 上下文切换需要保存和恢复
- (都要部分,见下总结)
- 协程栈
- 协程栈 通道和调度信息
- 协程栈帧 用户定义的数据
总结
- 上下文切换需要保存和恢复:“都要” 指:
- 寄存器:程序计数器(PC)、堆栈指针(SP)、状态寄存器、通用寄存器等。
- 状态信息:包括进程或线程的优先级、标识符、状态等
- 上下文切换需要保存和恢复:“都要” 指:
选用
- 指导版
- 越往上隔离越好,越往下则上下文的切换消耗越小
- 具体版
- 进程
- CPU密集型 (充分利用多核)
- 用户操作权限高 (利用隔离与崩溃不影响,如Linux多用户、Docker多容器)
- 线程 / 协程
- I/O密集型 (因为IO处理主要为等待时间,而处理时间极短。即切换频繁,减少切换损耗是重中之重)
- 高并发 (高并发也意味着切换次数多,1s内的切换次数非常高。即切换频繁,减少切换损耗是重中之重)
- 快速响应 (快速响应需要上下文开销小)
- 进程
- 落地版
- 多进程:Web服务器(如 Apache HTTP Server,支持多种)、某些数据库服务器(如PostgreSQL的早期版本)、传统的UNIX系统服务、Linux的多用户、Docker、云主机
- 多线程:Web服务器(如 Apache HTTP Server,支持多种)、某些数据库服务器(如MySQL)
- 多协程:Python的Tornado、asyncio库,Node.js的Express、事件循环
- GPT版
- 服务器对于多个客户端,有的选择多进程/线程/协程。 分别是哪些服务或库选择 多进程/线程/协程,为什么?
- 多进程:每个进程拥有独立的内存空间,这使得它们在稳定性上具有优势。如果一个进程崩溃,它不会影响到其他进程的运行
- 多线程:创建和上下文切换的开销较小。线程共享进程的内存空间,这使得线程间的数据交换更加高效。多线程模型适用于I/O密集型应用,因为线程可以在等待I/O操作完成时让出CPU给其他线程
- 多协程:适合于高并发、低延迟的网络应用,因为它们可以在等待一个操作完成时执行其他协程,从而提高资源利用率
冲突解决
原子变量在底层可能使用的一些技术
原语类
原子原语:由CPU直接支持,例如,通过使用特定的原子指令集,如x86架构中的
LOCK
前缀指令。这些指令可以确保当前指令执行期间,CPU不会执行其他内存操作,从而保证操作的原子性。原子指令:现代CPU通常提供了一系列原子指令,如比较并交换(Compare-And-Swap,CAS)、加载并链接(Load-Link)、存储并条件(Store-Conditional)等。
与原子原语有相似的地方:原子指令是一组封装了原子操作的指令,它们通常是由CPU原语构成的
同步原语
软件层面上实现线程间同步的一种机制。它们通常是由原子指令组成的,但提供了更高层次的抽象
内存屏障:(Memory Barrier)是一种硬件级别的同步机制,它可以确保屏障之前和之后的操作按照预期的顺序执行。在实现原子操作时,内存屏障可以防止编译器和CPU对指令进行重排序,确保操作的顺序性。
编译器支持:(非手动解决冲突)编译器也可能在生成代码时考虑到原子性。例如:通过插入适当的内存屏障或使用特定的CPU指令来确保操作的原子性
锁机制:虽然原子操作通常不使用传统的锁机制,但在某些情况下,硬件和操作系统可能使用一种特殊的锁(例如,总线锁或缓存锁)来确保只有一个处理器可以访问特定的内存区域