从一切皆数据与计算的角度,理解进程与线程
一切皆数据和对数据的操作(计算)
以下是思考意识流。
“进程和线程是什么?”,这是一个常见的程序员校招面试题,简单的回答是:线程是进程的一个实体,是 CPU 调度的基本执行单元,但线程不拥有资源。进程包含若干线程和资源(数据),一个进程至少有一个线程。
但总觉得这个解释缺点味道。一天想到冯·诺伊曼结构,对什么是进程和线程,有了另一个解释角度,觉得很有趣。
现在的主流计算机结构都是冯·诺伊曼结构,这个结构有两个最基本的抽象,就是数据和计算(对数据的操作),
CPU/GPU 负责计算,内存/磁盘 负责存储数据,IO 设备(键盘,鼠标,网卡,显示器,打印机等等)负责传输和展示数据。
回到进程与线程,首先,进程与线程,是哪个层级的概念?CPU并没有这个概念,进程和线程是操作系统层级的概念。
而且是操作系统的内核态概念,进程和线程,是两个操作系统内核对象。
什么是“内核”?什么是“对象”?
回到一切皆数据与计算的角度,“对象”也是一种“数据”,是操作系统用于描述特定行为和内容的一种抽象。比如,Windows的线程对象的数据结构(数据结构:数据长什么样子)是这样:
上图引用自:Windows 进程与线程管理 - 知乎
那什么是内核?就是:这里的事情由操作系统说了算(定义对数据的操作范围),其它的程序无权过问,操作系统只提供特定的 API 供外界(用户态程序)调用。
再看 “线程是 CPU 调度的基本执行单元” 这句话,其实就有问题了,调度线程的,不是 CPU,而是操作系统,操作系统根据一定的规则(比如时间分片轮转)来让 CPU 执行线程中包含的指令。
补充回答 “进程和线程是什么?” 这个问题:
进程和线程是操作系统层面的概念,本质上就是两个操作系统内核对象:即操作系统定义的两个数据结构,操作系统通过这两个数据结构,来管理程序的运行。
(1)以多进程形式,允许多个任务同时运行;
(2)以多线程形式,允许单个任务分成不同的部分运行;
(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。
这三点直接引用自:进程与线程的一个简单解释 - 阮一峰的网络日志
再回到一切皆数据与计算,会发现计算机世界所有事情都可以放在这个模型下思考。
除了上面提到的对硬件设备的分类,还有:
主板上为什么要分控制总线,数据总线和地址总线;控制总线对应计算(对数据的操作),数据总线对应了数据本身,地址总线确定应该操作哪里的数据。
所有的云端产品,基本上分为云计算相关和云存储相关。
各种协议,就是定义了数据应该长什么样,对数据有哪些操作。
数据和计算,在不同的层级和领域,有不同的别名。
数据的别名:对象,模型,实体,文件,桢,流等等。
计算的别名:编码解码,读取/写入/拷贝(对数据的转移,也算一种计算吧)等等。
发现一个心法就是,如果遇到什么陌生的概念,可以思考这么两个基本问题:
1 这个概念是谁定义的(属于哪个层级的概念)。
2 这是一个数据概念,还是一个计算概念。
其它的比如:
为什么要定义这个概念,与它一起工作的其它概念有哪些?这个概念的底层概念是什么?上层概念是什么?与这个概念相关的操作有哪些?这个概念有没有演化路径?其它地方有没有相似的概念?
想一遍这些问题,可以快速找到这个概念的定位,不至于一脸蒙圈,觉得很神秘。
第一次听说“内核对象”这个概念时就觉得很神秘,很厉害的样子,但还原到:“内核对象就是操作系统定义的一系列数据结构,内核则是一个逻辑概念,对于内核对象,操作系统只提供特定 API 供外部调用。” 这句话时,思路就清晰多了,虽然对于很多细节还是不懂。
闲扯结束。