共道人间惆怅事,不知今夕是何年。 收藏本站
登陆 / 注册 搜索

阅读: 5.9K   回复: 3

一个进程的自述

仗剑天涯论坛大牛 2017-7-2 13:21 |显示全部楼层

今生相逢便是缘分,何苦去怨恨,何苦去仇视。

主题破百
        我听说我的祖先,一生只能帮助人类做一件事,如果你想在这些专用“计算机”上干点别的事儿,例如安装个游戏玩玩,那是绝对不可能的,除非你把它拆掉,然后建一个全新的机器。而我这些祖先们勉强可以称为“程序”。
' ~+ ^8 a8 U: e) d' @) s4 U: L7 j1 u* m3 v
        后来有个叫冯诺依曼的人,非常了不起,他提出了“存储程序”的思想,并且把计算机分为五大部件:运算器、控制器、存储器、输入设备、输出设备。4 |2 @. l9 C, h% l6 f/ F
7 R) d9 Q7 z/ b/ l9 m, o# ?
        各种各样不同功能的程序写好以后,和程序使用的数据一起存放在计算机的存储器中,即“存储程序”;然后,计算机按照存储的程序逐条取出指令加以分析,并执行指令所规定的操作。
; X% V& m3 ~, A* p$ g" l# g' x* p+ x! p
) Q+ b) A8 [0 d5 ~" M
一个进程的自述 Life-of-process-visual3.jpg
0 n/ I% ~! d# Z, P. I& Z: I
        这样一来,原来的专用计算机变成了通用的计算机,不管你是计算导弹弹道的,模拟核爆炸的,还是计算个人所得税的,统统都可以在一台机器上运行,我就是其中的一员:专门计算员工的薪水。
2 X3 `7 G. L5 Q/ a% \  }
: [3 G: G7 E0 U% v1 J
进 程 的 诞 生

8 C) H: n- m+ G$ D+ g4 V/ D        我所在的计算机是个批处理系统,每次上机时,我和其他程序都排好队,一个接一个的进入内存运行。
+ \" X% I2 _% s( D: w1 r9 |; b5 K4 V
        每个月末是发薪日,我都要运行一次,这样我每月都能见一次CPU阿甘,这个沉默寡言,但是跑的非常快的家伙。我知道内存看阿甘不顺眼,还告了它一状,说他一遇到IO操作的时候,就歇着喝茶,从来不管不问内存和硬盘的忙的要死的惨境。
7 }. i8 P% ~0 ?" y
( J# Z5 z8 M' L/ \. v; H0 v, \        其实我倒是觉得挺好,这时候正好和阿甘海阔天空的聊天,他阅程序无数,知道很多内部消息,每一个字节都清清楚楚,和他聊天实在是爽。. @9 k3 V9 y' d. }

( I: Q( {& D  B3 l6 Y/ U, Q        又到了月末发薪水的时候,我刚一进入内存,便看到这么一个公告:
: ]  B+ k0 @9 G- H4 R5 J
2 ]3 V/ b4 ]' L# K& ?        公告6 R) ]% f6 M- ~8 j
        为了创建和谐社会,促进效率和公平,充分发挥每一个人的能力,经系统党委慎重研究决定:本系统自即日起,正式从“批处理系统”转为“多道程序系统”,希望各部门通力配合,一起完成切换工作。
: J  A. A" p  [  B! }3 z        系统党委
) O- {2 J# Q/ Q8 b' q        xxxx年xx月xx日4 N3 K) Y' g  {; R. d9 }; y
4 v/ d2 B) `1 w+ O7 x% {, A# `
        我正想着啥是多道程序系统,阿甘便打电话给内存要我的指令开始运行了。和之前一样,运行到了第13869123行,这是个IO指令,我欢天喜地的准备和阿甘开聊了。
5 Q9 I% p+ J2 k$ \/ r) @) b. _1 [% s6 j, v! g' _% C% g% F" u0 ^
        阿甘说:哥们,准备保存现场吧,我要切换到另外一个程序来运行啦!
; q0 T4 X2 B: L8 N
( @2 W& u* j8 b+ P        “啊?我这正运行着呢!咱们不喝茶了?
' }% s+ p; T3 e* z$ f  [# m1 q  ?6 [! V0 N2 K. I
        “喝啥茶啊,马上另外一个程序就来了!”2 K# I* ~* Q4 L) n- u0 C+ {7 Z3 z" {
8 I% y: }% w; j0 |' f
        "那我什么时候回来再见你?”我问道。
" r7 b( B8 A2 X$ ?# @9 {
) A5 l$ |7 Z) S% f0 J. b        “等这个IO指令完成,然后操作系统老大会再给你机会运行的。”  ~7 u: M, Q0 O2 Y

. Q/ c1 v$ Y" H. x5 z) x# T: d        “那谁来记住我当前正在运行第13869123行?还有刚把两个数据从内存装载到了你的寄存器,就是那个EAX,EBX,你一切换岂不都丢了?”我有点着急。! X6 I/ t  U5 n4 v

8 `& m2 L: ~0 ?        阿甘说:“所以要暂时保存起来啊,不仅仅是这些,还有你的那些函数在调用过程中形成的栈帧和栈顶,我这里用寄存器EBP和ESP维护着,都得保存起来。”; _1 V2 W; b( U9 U/ j# b
4 T6 A7 l, W. d! L4 W  f
        “还有”阿甘接着说,“你打开的文件句柄,你的程序段和数据段的地址,你已经使用CPU的时间,等待CPU的时间。。。。。。以及其他好多好多的东西,统统都要保存下来。”+ ?7 l: Z4 Q. a, _* A  [

8 q" x. }1 r& V! W; P6 p        我瞪大了眼睛:“这也太麻烦了吧,原来我只需要关心我的指令和数据,现在还得整这么多稀奇古怪的东西”
7 Z1 W, F- r6 R; |9 Z! L
9 z! ^% \- ]4 C6 N" |        “没办法,这就叫做上下文切换,把你的工作现场保存好,这样下一次运行的时候才能恢复啊。对了,老大给你们统一起了一个新的名称:进程!刚才那些需要保存的东西叫做叫做进程控制块(Processing Control Block,PCB),”
* f4 p9 L* ]* m, m. z/ V' [+ \+ P* u; \; W
        我想了想,这个名字还挺贴切的,一个真正进行的程序!只是这个正在进行的程序随时可以被打断啊。& h" _& `$ m9 Z: j! ?# }
/ B/ D0 S0 M1 {2 \
        我只好保存好上下文,撤出CPU,回到内存里歇着去了,与此同时另外一个程序开始占据CPU运行。7 d& P8 k4 p2 S( p7 q2 w) x
( t2 j3 F; \' q) i( d$ M8 c0 U
        其实我这个程序,奥,不对,我这个进程被放到一个阻塞队列里,等到IO的数据来了以后,又被赶到了就绪队列中,最后才有机会再次运行,再次见到CPU阿甘。
/ ]3 V- ^1 \7 q  M8 W$ q& G9 @# P; `* S$ ~! {& w
        //进程的就绪,阻塞,运行这三个状态的转换和《一个线程的自白》中描述的非常类似。
" k+ U% I3 ], ]7 r! _
4 {. ~  u) k. j7 i* _: h        阿甘从我的PCB中取出各种保存的信息,恢复了运行时现场,可是忙活了好一阵,没办法,这就是程序切换必须要付出的代价。. k) W' }0 h$ }' g- p: P3 S+ H
( w1 f; _" I' G' t3 O
        我有点同情阿甘了,从此以后,他很难再悠闲和和我们海阔天空,每时每刻都处于高速的奔跑中。#j319:0 o2 |) \: c6 u

4 j+ r! v6 W3 q; |  b. Y  t. `        得益于阿甘的高速度,虽然在同一时刻只有一个程序在运行,但是有很多程序在短时间内不断的切换,在外界看来,似乎多个程序在同时执行。% l; ]$ @$ V% t
2 ?( i% C% F  }, w0 ^* L
        尤其是那些速度超慢的人类,他们开着电脑一边听歌,一边上网,一边QQ,很是自在,理所当然的认为这些程序就是同时在运行。岂不知阿甘是让音乐播放器上运行几十毫秒,然后打断,让浏览器进程运行几十毫秒,再打断,让QQ也运行几十毫秒,如此循环往复。#j334:2 [0 u1 P6 \2 l. F& L+ p

( Y8 ~% B' z8 D* w" T# r  w/ T$ ]        唉,阿甘真是能者多劳啊,这个计算机系统也算是达到了我们党委的目标:兼顾了效率和公平。
8 O5 [7 O" s( G1 u! J7 X, w/ B) \. b9 [' |
线 程
6 [% i8 a# c" c8 r$ Q: Y! B& h
        有了进程就万事大吉了吗?人类的欲望是无止境的,很快就出现了新情况,举个例子来说吧,我有一个兄弟,是个文字处理软件,他和我不一样,他有界面,人类在用的时候能看到,这实在是很幸福,不像我总是在背后默默工作,几乎无人知晓。
& F; ^" {6 J2 }+ z6 h5 k5 l, S6 {3 K0 f& w
        这哥们有个智能的小功能,就是在人类编辑文档的时候能自动保存,防止辛辛苦苦敲的文字由于断电什么的丢掉。% d! }9 F" y9 m! ~, x+ F

3 I( M0 I0 ]+ ?: S7 c: y        可是这个功能导致了人类的抱怨,原因很简单,自动保存文字是和IO打交道,那硬盘有多慢你也知道,这个时候整个进程就被挂起了,给人类的感觉就是:程序死了,键盘和鼠标不响应了!无法继续输入文字,但是过一会儿就好了。- D3 i1 a* u# {
1 O  W' ?4 [# t, g6 }4 i0 R6 U6 ]" W
        并且这种假死一会儿就会出现一次(每当自动保存的时候),让人不胜其烦。  o( H5 Y" u8 u! C+ J% g% {& [2 J) r
5 v* u" n1 a' N
        系统党委研究了很久,他们当然可以用两个进程来解决问题,一个进程负责和用户交互,另外一个进程负责自动保存,但是,这两个进程之间完全是独立的,每个人都有自己的一亩三分地(地址空间),完全互不知晓,进程之间通信的开销实在是太大,他们没有办法高效的操作那同一份文档数据。
" z$ o3 e4 o/ q8 r% h3 E3 ^
( T) C& [$ u; g! q% i. |7 H: N        后来还是劳模阿甘想出了一招:可以采用多进程的伟大思想啊!) l' B2 S, f, h0 L9 T0 X! m% n% D
/ ~9 D  S$ g4 X% U$ x2 F8 p4 ~+ R
        把一个进程当成一个资源的容器,让里边运行几个轻量级的进程,就叫线程吧,这些线程共享进程的所有资源,例如地址空间,全局变量,文件资源等等。
# s2 n# z" X7 N  v7 e' \6 [  o9 A' T  y1 b: D
        但是每个线程也有自己独特的部分,那就是要记住自己运行到哪一行指令了,有自己的函数调用堆栈,自己的状态等等,总而言之,就是为了能像切换进程那样切换线程。0 R% H; L. o3 X* a% d! \
; |2 W- H; i* |$ i+ O! U
一个进程的自述 1-进程.jpg
9 Y! b1 n9 j) S
        拿我那个哥们的情况来说,一个进程保存着文档的数据,进程中有两个线程,一个负责和用户交互,另外一个专门负责定时的自动保存,IO导致的阻塞就不会影响另外一个了。
) j/ L3 E, p2 k+ q0 C$ X# p: j  d0 h9 C6 T+ t
        注意,这两个线程都能访问进程的所有东西,他们两个要小心,不要发起冲突才好--这是人类程序员要做的事情了,不归我们管。$ `; h. o4 s( s0 C4 i7 R
6 A. K0 L$ M, k" {: T% E. n5 O
争 吵
7 v- h! f/ v, L
        阿甘的建议被采纳了,其实这几乎是唯一的解决问题方式了,但是由谁来管理引起了激烈争吵。; d+ E; J, {8 o1 d

' i& t1 [) \$ T$ v7 d) l) W; R        系统党委有一波人坚持要在用户空间实现线程,换通俗的话说就是让那些进程在自个儿内部去管理线程,他们的理由也很充分:你们自己实现了线程,可以自己定制自己的调度算法,多灵活啊;' b8 d1 {% s: D  y7 y  @
3 ]0 g- m2 z. B$ E$ z
        所有的线程切换都在进程内完成,不用请求我们操作系统内核来处理,效率多高啊;
$ L8 l/ Z0 F, r- u& l+ H$ S, W9 i0 a* X: m
        况且你们可以在那些内核不支持线程的操作系统中运行,移植性多好啊。3 M# W$ |4 e- `7 s3 g0 J% ~  i

8 J' D0 u5 _& M
一个进程的自述 2-进程.png
$ ^* K) j, s' m0 j9 ?1 @/ o" y
        我们清楚的知道这是内核想做甩手掌柜,因为他们选择性的忽略了一个致命的问题:如果由我们实现线程,则操作系统内核还是认为我们只是一个进程而已,对里边的线程一无所知,对进程的调度还是以进程为最小单位。$ o( @. S, a) s
% I" H+ ]. K, b6 |) }  g. m# n
        一旦出现阻塞的系统调用,不仅仅阻塞那个线程,还会阻塞整个进程!1 r/ W2 |. G; B9 F% g
; o* I' L) H( Q4 I  _+ G6 A9 V
        例如文字处理器那个进程,如果负责定时保存的线程发起了IO调用,内核会认为,这是由进程发起的,于是就把整个进程给挂起了,虽然和用户交互的进程还是可以运行,也被强制的随着进程挂起来,不响应了,这多么悲催啊,又回到了老问题上去了。
6 ^# U7 U$ P5 \( T( p
) c# v6 M$ j) b" \        所以我们坚决不能答应,我们则一致的要求:在内核中实现线程!内核需要知道进程中线程的存在,内核需要维护线程表,并且负责调度!3 Z  N& g1 n) A6 W0 e7 \7 o. e! v

& f* V( x$ `( W; i4 j! W# G! x9 q; R
一个进程的自述 3-进程.png
4 t' C' I, Y( C1 s0 g8 ?
        党委的人傲慢的说:你们不嫌累吗,每次创建一个线程都得通过我们内核,多慢啊。2 D8 n2 \$ E: W3 r' I% @6 K
$ l% h1 L& r; H% K8 ]% X) N) \
        我们说:只有这样,一个线程的IO系统调用才不会阻塞我们整个进程啊,你们完全可以选择同一个进程的另外一个线程去执行。7 z, y( g" K& R% W- A

) x2 s  S0 X8 |/ d( e$ v6 t        双发僵持不下,最后只好妥协,那就是:混合着实现吧。* g, B. v& L4 U$ h- B

8 g7 m7 S% Y5 {0 U: ~        用户空间的进程可以创建线程(用户线程),内核也会创建线程(内核线程),用户线程映射到内核线程上。) Y5 G* x/ I+ b( E" f9 q  X
2 `2 @7 l- Q1 v1 `5 W" h
一个进程的自述 4-进程.jpg
+ ^4 p6 u% y- v
        问题基本解决了,但也带来了新的问题,我们的系统也变的越来越复杂,尤其是进程之间的通信和线程之间的同步,会那些程序员们带来无穷无尽的烦恼,这是后话了,有机会下次再说吧。+ P( D% r0 \: [- z' e7 q+ i
" C; _7 |: g0 T4 Y% e( R
上一篇
下一篇

评分

参与人数 1成长值 +1 金币 +1 展开 理由
清风徐来 + 1 + 1 热心回复!

查看全部评分


巴黎环抱的花海 「龙战于野」 2017-8-31 19:20 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

小白一个 顶一下
映画 「出类拔萃」 2018-1-20 22:35 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

你们有见过这么整齐的十五个字吗; y  W- X8 C- P6 O& [
这么整齐的十五个字人家最喜欢了
! Y! e0 ^7 X& C5 k8 I  m- F他们都说打出十五字才是最标准的; Q% E) |7 Z9 z) x+ \
我也没办法因为我要打十五个字啊* p, j+ \# C( U( n5 N* \0 N& D  V# V
我说了多少次了不要只打十五个字& R$ Q1 f1 b  j% e, ?
你们那些十五字神马的完全弱爆了
8 _+ W: `; n1 ?. J6 l$ y7 }; M都怪吧主删我贴所以我只能到处逛
/ ^2 _5 G/ h% X5 v. @为了经验我没办法只能遇贴就灌水
) v; o# S; p8 h, c7 \" U3 s灌水也要讲技术保证句句是十五字
$ b9 x9 s( S: u5 @' s5 w如今发帖有困难整不好就被删贴了9 H( K0 B# Q1 ~' m/ o; d
我也没办法吧主他老是删我帖子啊6 O" ^, m+ b0 [  t
只能够这样用十五字来混混经验了% j# N6 y- @  U! R! c; d; Q
用十五字混经验的有谁比我厉害呢  [4 y: k' U2 A& Z) R2 S, s. C
有前排就要占没前排也要灌一下水
/ ~) c/ L% l0 S+ r' K' F  G! _有前排不占或者不灌水是会后悔的8 ]3 t- d& _6 K: [
无论是多么无聊的帖子我都会去的
: r- W8 {( e+ G* _0 s因为为了一句话万一这贴子火了呢
& a5 y4 Y4 e" S句句十五个字有哪个高手能超越呢
  Q! l- f! E6 X5 i! \& I+ p#367:
深海里的那抹蓝 「龙战于野」 2018-1-20 23:45 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

尔等果如其母戏寡人欤?#y447:
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-6-20 03:12 , Processed in 0.030925 second(s), 22 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表