本文参考码农翻身公众号文章,并做了适当的调整和总结。
按照历史的脉络,执行程序的方式依次经历了批处理,进程和线程三个阶段,本文按照这个顺序,并以故事的形式来解释进程与线程的区别。
批处理
很久很久以前,有两个程序,暂且称他们为旺财和小强。
旺财和小强这两个程序都很长,每个都有十几万行。 他们两个的人生价值就是到CPU上去运行,把运行结果告诉人类。
CPU是稀缺资源,只有一个,他们俩必须排着队,轮流使用。
旺财从头到尾执行完了,让出CPU, 让小强从头儿去执行。
人类把这种处理方式叫做批处理。
进程
长久以来,两人相安无事。 后来CPU的速度越来越快, 远远超过了内存,硬盘的读写速度。
人类想到,这批处理系统的效率有点低啊,你看当小强需要从硬盘上读取数据的时候,CPU也一直在等待,这是多大的浪费啊!这时候完全可以让旺财来运行一下嘛!
当然,得保存好小强的执行现场:具体执行到那一行程序指令了, 函数调用到什么层次了,每个函数调用都有什么样的参数,CPU寄存器中的值..... 等等这一系列东西。
如果不把小强的执行现场给保存下来,等到小强的数据从硬盘读完了,就没法回到中断处来继续执行了。
这个执行现场,再加上小强的代码,就是一个执行中的程序,被称为“进程” 。
旺财和小强在运行的时候,也被改造成了进程。
人类还规定:进程不能长时间占据CPU, 只能在CPU上执行一小会儿,然后马上切换到别的进程去执行。
这样,通过引入进程和规定每个进程在CPU上的最长执行时间,极大的缓解了CPU浪费的问题,同时进程也自然而然的成为了资源分配的基本单元。
线程
后来的后来,旺财有了界面,还能访问网络,每当它联网的时候(这也是个非常非常耗时的操作),就得把CPU让给小强。
即使旺财再次被调度执行,由于网络数据还没有返回,他必须等待,什么事情都做不了,在人类看来,界面根本无法操作,旺财不响应了!气得人类经常把旺财kill掉。
旺财心里苦,他很纳闷小强怎么就没有问题,小强不是要读写硬盘吗? 那也是很慢的操作啊。
小强说:“你傻啊,内部只有一个执行的流程,一遇到耗时的操作就得等待,你看看我,内部搞了两个执行流程(线程),一个用来读写硬盘(T1),另外一个处理界面(T2)。我和操作系统商量好了,如果T1在读写硬盘, 就可以调度我的T2来执行,这样界面至少还可以操作。 ”
旺财觉得很有意思,也采用了类似办法。
于是,一个进程中至少有一个执行的流程(主线程),也可以开启新的执行流程(线程)。
这样,通过在进程中引入线程并和操作系统商量以线程为基本的调度单位,就解决了拥有界面的进程在进行耗时操作时,无法响应的问题。
总结
- 批处理就是程序一个一个排着队执行。
- 通过引入进程和规定每个进程在CPU上的最长执行时间,极大的缓解了CPU浪费的问题,同时进程也自然而然的成为了资源分配的基本单元。
- 通过在进程中引入线程并和操作系统商量以线程为基本的调度单位,就解决了拥有界面的进程在进行耗时操作时,无法响应的问题。
- 进程切换涉及到资源的重新分配,所以其时间损耗远远大于线程切换(多个线程共享进程的资源)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。