Linux 基础之进程、线程、纤程和中断

进程和线程

  • 进程 是 OS 分配资源的基本单位。一个进程对应一个端口号, OS 会为每一个进程 独立分配一部分资源,最重要的资源是独立的 内存空间
  • 线程 是 CPU 执行 调度 的基本单位。

一个程序可以启动多个不同的进程,如 QQ.exe 可以多个;一个进程也可以启动多个线程,不同的执行路径就是线程。(《linux 内核设计与实现》可以看懂)

线程与进程最重要的区别:线程共享进程的内存空间,它没有独立的内存空间。(所以并发中需要考虑竞争问题)

线程在不同操作系统中实现不一样。linux 中的线程就是一个进程,它是 fork 出来的,相当于 clone 出来一个进程但共享同一个系统资源;其他操作系统中线程叫 LWP(Light Weight Process)轻量级的进程。

(内核还有自己启动的线程叫“内核线程”,它不是用户空间启动起来的,与用户程序没有关系,是内核的。)

纤程

纤程:也有人称作 fiber,Go 中叫 Goroutine(协程),它是 用户空间 的“线程”。

JVM 运行在用户空间,当它 new 一个 Thread 时,会对应在 OS 中起一个线程(内核空间),所以这叫重量级线程。所以 JVS 中的一个线程映射到内核中的一个线程(这种在其他地方可能是一对多的)。而纤程则是在用户态有多条(如在 JVM 层级去协调调度)。所以,

纤程的好处:在 用户态,不与内核打交道,所以更快,存在的个数也更多(几万、几十万个都行)。

具体优势:

    1. 占用资源少。一个真正的线程占内核大概 1M 的空间,而纤程只占 4k 的空间。
    1. 切换简单。
    1. 启动 10w+ 没问题。

内部实现:用户程序可以自己实现一个栈,自己实现调度。

实现纤程的语言:Go、Kotlin、Python(lib)。Java 在类库中有,但不成熟。

进程

linux 中一个进程也叫 task。
资源:独立的地址空间、内核数据结构(PCB)、全局变量、数据段……
linux 中有个 数据结构 叫 PCB,Process Control Block 进程描述符,每一个进程都有一个它,linux 管理的时候就使用它,将详细的进程信息都放在这个结构里面。

僵尸进程

当 A fork 出 B、C、D 时,A 为 B、C、D 的父进程。子进程不会去主动释放资源,而是由父进程去管理的。

当子进程结束后,父进程没有将对应子进程的 PCB 释放,那子进程就是僵尸进程,它只有一个 PCB(数据结构)。

僵尸进程没关系,没什么影响。如果多了才有影响(自己用 C 语言再考虑吧)。

孤儿进程

子进程还没执行完,父进程退出了。孤儿进程会成为 init 进程的孩子,由 1 号进程维护。

孤儿进程也没什么影响。会由 init 去管理、释放资源。

进程(任务)调度

linux 可以给不同的进程实行不同的调度方案。

单任务(独占)多任务(分时) ,原则:压榨 CPU 资源。

多任务

  • 非抢占式:除非进程让出 CPU,其他进程就没机会执行
  • 抢占式:由进程调度器强制开始或暂停(抢占)某一进程的执行。

进程调度实现

linux 2.5 经典的 Unix O(1) 调试策略,偏向服务器,但交互不友好。为什么呢,它的策略是 相等的时间片轮转,比如将每个任务分配 10ms,一直在轮转执行。“交互不友好”就是在交互的进程与后台进程有同样的比例,看上去公平,其实不公平。

linux 2.6 采用 CFS 调度策略,叫 完全公平的调度策略(Completely Fair Scheduler)。它的“公平”是按优先级来分配 时间片的比例,如果一个进程的执行时间不到它应该分配的比例,优先级就会变高。

进程调度.png

默认的调度策略

  • 实时进程 > 普通进程
  • 实时中 FIFO > RR (Round Robin)
  • 普通进程的策略是 CFM(完全公平调度策略)
默认调度策略.png

中断

硬件操作系统 通信 的一种机制。

如果 CPU 正在运算,那也需要进行其他处理,比如你使劲敲键盘,这个时候就发生一个中断。
只要有硬件上的事件,都需要优先执行,都需要中断。

中断 -> 中断表 -> 对应程序 -> 放入 CPU

中断还分软中断,上面的可以说是硬中断。软中断是 0x80 级中断,是软件发起的中断。

你可能感兴趣的:(Linux 基础之进程、线程、纤程和中断)