提纲:

🔥进程&线程&协程

  • 用户态与内核态

  • 进程

  • 线程

  • 协程

一、进程&线程&协程

1. 用户态与内核态

  • Linux 的虚拟地址空间为 0 ~ 4G,其中高地址开始 1G 为内核地址,低地址开始 3G 为用户进程的内存地址,用户进程间的内存是隔离的,内核的内存是进程共享的,每个进程都可以通过系统调用进入内核态

  • 内核空间中存放的是内核代码与数据,进程空间存放的是进程的代码与数据,不论是哪一个,都是处于虚拟内存空间当中的

  • 上下文切换

    • 1、系统调用:例如进程发出一个 open() 指令打开文件,write() 指令写文件,都会让进程从用户空间进入内核空间,但不会发生进程上下文切换,这种切换也称为特权模式切换,只会发生 cpu 寄存器指令位在用户与内核间的切换

    • 2、进程上下文切换:进程是由操作系统内核负责管理,因此进程间的切换必须在内核状态中发生,进程的上下文切换不仅包括了用户态的虚拟内存的切换,还包括内核态的堆栈以及 cpu 寄存器、TLB 等的切换

      • 常见的进程切换场景

        • 1、cpu 调度算法基于时间片轮转,时间片耗尽后触发一次进程的上下文切换

        • 2、硬件中断,例如网络 I/O,cpu 上正在运行的进程就会被挂起,执行内核中的服务

        • 3、进程运行时的资源无法满足,例如内存

2.进程

  • 进程是应用程序基于某个数据集进行的一次运行,是系统资源分配的最小的单位,包括代码、堆、I/O 文件等

  • 通信方式

    • 1、管道 pipe:用于有亲缘关系的进程间的字节流通信

      • 半双工,一种特殊的可以读写的文件,位于内存中,通过 pipe() 系统调用来创建

    • 2、命名管道 named pipe:在pipe基础上,可以用于任意两个进程间的数据通信

      • 通过 mkfifo() 系统调用来创建,在磁盘中有对应的节点,但是没有实际存储的数据块,也就是拥有一个文件名,可以通过这个文件名与任何进程进行读写

    • 3、信号 signal:用于通知和接收事件的发生

      • 传输数据量小,例如 I/O 事件的消息

    • 4、消息队列:克服了信号数据承载量小、管道只能传输无格式字节流数据且缓存受限的缺点,以FIFO的方式进行数据的存入与取出,且可以实现消息的随机查询,也可以按照消息的类型读取。

      • 消息队列存在内核中,只有当系统重启或显示删除消息队列时才会清除,可能会读到上一次通信没有读完的部分