进程

有了进程之后,即使 cpu 只有一个,但是他们也有并发的能力,它们将单独的 cpu,变换成多个虚拟的 cpu,就好像每个程序进程都有自己独占的 cpu 一样。

一个进程是一个正在执行的程序实例,包括程序计数器、寄存器、变量的当前值,从概念上来说,每个进程都有自己虚拟的 cpu。

虚拟 cpu 的实现方式是,cpu 由一个进程快速切换到另一个进程,每个进程运行几十或几百毫秒,严格来说,在某一瞬间,单核 cpu 只能运行一个进程。

创建

场景

  1. 操作系统启动的时候创建
  2. 一个正在运行的进程,通过系统调用,创建新的进程协助工作。
  3. 在交互式系统中,输入一个命令,或者双击图标,可以启动一个程序,开启一个新的进程

从技术角度来说,新进程,都是由已经存在的进程,通过系统调用来创建的。

  1. 在 unix 中,通过 fork 调用,这个系统调用会创建一个和调用进程相同的副本。父子进程拥有相同的内存镜像、同样的环境字符串、同样的打开文件。通常,子进程会接着执行 execve 系统调用,来修改内存镜像,并运行一个新的程序
  2. windows 中,可以通过调用 CreateProcess 来创建新的进程

在 windows 和 unix 中,进程创建后,父进程和子进程拥有不同的地址空间,如果某个进程在它的地址空间修改了个字,其他进程是不感知的。

  1. 在 unix 中,子进程的地址空间是父进程的镜像,读的时候是可以共享的,如果要写的话,就会写时复制,写的内容会写到自己的私有空间。
  2. 在 window 中,创建子进程的时候,就是不同的地址空间。

终止

场景

  1. 程序逻辑自己在正常退出。
  2. unix 中,调用 exit,或者界面上的一些退出菜单项
  3. window 中的,ExitProcess 调用
  4. 严重错误异常退出,致命错误,进程会收到中断信号
  5. 被其他进程杀死
  6. 例如 unix 中的 kill 命令
  7. window 中的 TerminateProcess 调用

层次结构

一个进程,可以有 0 个,或者多个子进程。

  1. 在 unix 中,系统启动的时候,有一个 init 特殊进程,然后这个进程开始创建其他子进程,子进程再创建其他进程。就形成了一个树状结构,init 进程就是根
  2. windows 中没有进程层次概念,所有进程地位都是相同的

进程的状态

尽管每个进程是一个独立的实体,有自己的程序计数器和内部状态,但是进程之间需要有相互作用通信,例如

cat a.log b.log | grep ERROR

有可能 grep 已经准备就绪可以运行,但是输入还没完成,这个时候必须阻塞 grep。

进程的 3 种状态

  1. 运行态,该时刻实际占用 cpu
  2. 就绪态,可以运行,但是因为 cpu 正在运行其他进程,暂停着
  3. 阻塞态,除非某种外部事件发生,否则不能运行,监听事件触发

进程的实现

操作系统维护一张表格,即进程表。每个进程占用表格的一行,每行里有该进程的重要信息,例如状态,程序计数器,堆栈等。

线程

每个进程有一个地址空间和一个控制线程。随着技术发展,一个进程下有多个线程。

进程用于把资源集中在一起,线程是被 cpu 调用执行的实体。

同一个进程中并行运行多个线程,是对一台计算机中并行运行多个进程的模拟。

  1. 前一种:多个线程共享进程里的地址空间和其他资源
  2. 后一种:多个进程,共享计算机的物理内存和其他硬件资源

多线程的优势

  1. 多个线程之间可以共享地址空间,进程地址空间是独立的
  2. 线程比进程轻量,cpu 切换多线程速度快

多线程和进程共享的内容

进程中被线程共享的 线程中独立的内容
地址空间 程序计数器
全局变量 寄存器
打开文件 堆栈
子进程 状态
账户信息等
最后修改:2023 年 12 月 30 日
如果觉得我的文章对你有用,请随意赞赏