我们不应该根据背负的罪孽来选择道路,而应在选择的道路上背负自己的罪孽。 收藏本站
登陆 / 注册 搜索

阅读: 6.4K   回复: 3

一个进程的自述

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

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

主题破百
        我听说我的祖先,一生只能帮助人类做一件事,如果你想在这些专用“计算机”上干点别的事儿,例如安装个游戏玩玩,那是绝对不可能的,除非你把它拆掉,然后建一个全新的机器。而我这些祖先们勉强可以称为“程序”。
7 f5 Q+ q2 R7 Z) D) o" |% s. ~8 L' c/ q! d- e4 q! N
        后来有个叫冯诺依曼的人,非常了不起,他提出了“存储程序”的思想,并且把计算机分为五大部件:运算器、控制器、存储器、输入设备、输出设备。2 ~$ W9 f1 D+ B/ ~2 t4 {% R4 H$ w

- z! |3 S$ x& t2 K        各种各样不同功能的程序写好以后,和程序使用的数据一起存放在计算机的存储器中,即“存储程序”;然后,计算机按照存储的程序逐条取出指令加以分析,并执行指令所规定的操作。9 G# O* t6 `6 _6 C  v6 |
) m6 y' D8 @8 _3 F, l( j. A, m
一个进程的自述 Life-of-process-visual3.jpg

: f1 E2 L0 o, ]5 z) e        这样一来,原来的专用计算机变成了通用的计算机,不管你是计算导弹弹道的,模拟核爆炸的,还是计算个人所得税的,统统都可以在一台机器上运行,我就是其中的一员:专门计算员工的薪水。
5 Z3 \* b% `; Y  }3 z: |' _! i* y  L7 a% U6 d+ g, }
进 程 的 诞 生

' Y0 A( I6 t$ z& {# _( @) T        我所在的计算机是个批处理系统,每次上机时,我和其他程序都排好队,一个接一个的进入内存运行。
* Z0 w0 D0 A0 k/ ~  x9 m' [) _8 i/ _3 j+ f- [: J( W- Y
        每个月末是发薪日,我都要运行一次,这样我每月都能见一次CPU阿甘,这个沉默寡言,但是跑的非常快的家伙。我知道内存看阿甘不顺眼,还告了它一状,说他一遇到IO操作的时候,就歇着喝茶,从来不管不问内存和硬盘的忙的要死的惨境。
8 Y* C' w6 l3 l
# W' r# w. F: Q+ K        其实我倒是觉得挺好,这时候正好和阿甘海阔天空的聊天,他阅程序无数,知道很多内部消息,每一个字节都清清楚楚,和他聊天实在是爽。
! `9 e6 C/ ]! P6 F
" i7 M- n# `+ B& C        又到了月末发薪水的时候,我刚一进入内存,便看到这么一个公告:) F3 W7 p9 R7 X1 v; ]

( {/ E! E) |8 H9 b. ]4 ~% e. T1 H        公告
1 x6 v1 @: k: @' i2 M! ]1 \        为了创建和谐社会,促进效率和公平,充分发挥每一个人的能力,经系统党委慎重研究决定:本系统自即日起,正式从“批处理系统”转为“多道程序系统”,希望各部门通力配合,一起完成切换工作。
6 U6 t# |/ C0 U/ u        系统党委
  L5 u5 u. E: g  L" N; ^  o$ ]9 B9 ~        xxxx年xx月xx日
+ N* B/ G1 @0 ]9 V3 {2 |" |
" h* @% p- M: f        我正想着啥是多道程序系统,阿甘便打电话给内存要我的指令开始运行了。和之前一样,运行到了第13869123行,这是个IO指令,我欢天喜地的准备和阿甘开聊了。4 f( |) {5 t- f& h3 w$ Q
: w+ J- l+ x! ?7 p& M" W
        阿甘说:哥们,准备保存现场吧,我要切换到另外一个程序来运行啦!
! Z+ q2 P# B3 D& M  Q* \: l+ s. L4 {) K; Y! S/ e
        “啊?我这正运行着呢!咱们不喝茶了?
1 I1 Q7 q. W' V( V) B7 z" }. h
/ ?5 }# f6 w0 t0 I. j* e; i        “喝啥茶啊,马上另外一个程序就来了!”* m: i; h0 X8 D, [$ v

7 M& {; p* U; L# t        "那我什么时候回来再见你?”我问道。9 x# i# ]# d" R/ Y
: F% R7 S/ N( t9 y  @2 [' z9 G
        “等这个IO指令完成,然后操作系统老大会再给你机会运行的。”: Q) Y9 v- _+ R7 p3 a
9 K% t: U& D* e# l" Z3 R
        “那谁来记住我当前正在运行第13869123行?还有刚把两个数据从内存装载到了你的寄存器,就是那个EAX,EBX,你一切换岂不都丢了?”我有点着急。" O- p/ W7 G  M( j9 o- j4 A1 }
. ~0 g. [6 O" Y0 D$ k
        阿甘说:“所以要暂时保存起来啊,不仅仅是这些,还有你的那些函数在调用过程中形成的栈帧和栈顶,我这里用寄存器EBP和ESP维护着,都得保存起来。”6 y% Y  N4 X, o- R9 ^

$ N; T$ W3 q( h: P        “还有”阿甘接着说,“你打开的文件句柄,你的程序段和数据段的地址,你已经使用CPU的时间,等待CPU的时间。。。。。。以及其他好多好多的东西,统统都要保存下来。”- y* G. d* ^7 d$ p+ E
. H2 R) Q9 C! e1 Z6 l7 e$ M9 f
        我瞪大了眼睛:“这也太麻烦了吧,原来我只需要关心我的指令和数据,现在还得整这么多稀奇古怪的东西”/ Y) h4 c! ?3 W, X% |
5 Z, U! k+ E& q* \) Q8 R
        “没办法,这就叫做上下文切换,把你的工作现场保存好,这样下一次运行的时候才能恢复啊。对了,老大给你们统一起了一个新的名称:进程!刚才那些需要保存的东西叫做叫做进程控制块(Processing Control Block,PCB),”3 R) ?; J, S; _. Z; y
) r( z0 x3 f! C/ w8 }+ l2 N' ?
        我想了想,这个名字还挺贴切的,一个真正进行的程序!只是这个正在进行的程序随时可以被打断啊。( A1 a8 G7 X5 \0 ]2 j3 j
1 l3 F1 _9 q4 |& M
        我只好保存好上下文,撤出CPU,回到内存里歇着去了,与此同时另外一个程序开始占据CPU运行。
7 _2 l3 M! ?( Q0 ?: C) }/ N5 E+ N/ U& e7 ]
        其实我这个程序,奥,不对,我这个进程被放到一个阻塞队列里,等到IO的数据来了以后,又被赶到了就绪队列中,最后才有机会再次运行,再次见到CPU阿甘。, }& y5 G" V: w+ Q/ ?9 y4 P; ^% U4 q+ F

1 V6 z; e3 i1 q; p        //进程的就绪,阻塞,运行这三个状态的转换和《一个线程的自白》中描述的非常类似。
! A4 R3 Z6 t5 C. L' k+ K: _% X& A. K8 v
        阿甘从我的PCB中取出各种保存的信息,恢复了运行时现场,可是忙活了好一阵,没办法,这就是程序切换必须要付出的代价。
6 T( R/ S# w  t& w5 F/ {/ P7 Y- L$ A8 b( `6 O6 {1 i9 l5 u
        我有点同情阿甘了,从此以后,他很难再悠闲和和我们海阔天空,每时每刻都处于高速的奔跑中。#j319:
4 o& t6 t! @0 W% {' ]: w6 U9 R+ N7 r, c4 V1 O% x1 @3 ?
        得益于阿甘的高速度,虽然在同一时刻只有一个程序在运行,但是有很多程序在短时间内不断的切换,在外界看来,似乎多个程序在同时执行。6 f3 G1 X% ]. ~3 P0 E
! d6 F# m! e/ e: S; r  e/ [0 J2 H( u
        尤其是那些速度超慢的人类,他们开着电脑一边听歌,一边上网,一边QQ,很是自在,理所当然的认为这些程序就是同时在运行。岂不知阿甘是让音乐播放器上运行几十毫秒,然后打断,让浏览器进程运行几十毫秒,再打断,让QQ也运行几十毫秒,如此循环往复。#j334:4 ^5 b0 O  z' h# B
3 U! @3 b  ?' h
        唉,阿甘真是能者多劳啊,这个计算机系统也算是达到了我们党委的目标:兼顾了效率和公平。
* w. f( ~0 h" U9 i, Y3 w# L1 }) J9 _% `7 i8 l8 P! ^
线 程
& Q$ I3 m; f& F  H  h  U. `5 y
        有了进程就万事大吉了吗?人类的欲望是无止境的,很快就出现了新情况,举个例子来说吧,我有一个兄弟,是个文字处理软件,他和我不一样,他有界面,人类在用的时候能看到,这实在是很幸福,不像我总是在背后默默工作,几乎无人知晓。2 P( \, h) v' M- Y6 h7 p. z
; Z7 v! r' m8 R% _# s
        这哥们有个智能的小功能,就是在人类编辑文档的时候能自动保存,防止辛辛苦苦敲的文字由于断电什么的丢掉。
! X! g! y) Y* h) y2 y6 |' U# k1 _7 l) c- E# ~
        可是这个功能导致了人类的抱怨,原因很简单,自动保存文字是和IO打交道,那硬盘有多慢你也知道,这个时候整个进程就被挂起了,给人类的感觉就是:程序死了,键盘和鼠标不响应了!无法继续输入文字,但是过一会儿就好了。
! j0 S- d* G* |, F; @0 x6 ?/ i  z3 V; o# n4 N, o; r1 ~- B
        并且这种假死一会儿就会出现一次(每当自动保存的时候),让人不胜其烦。
$ k# y( Q9 _8 X6 X9 H  c' e. g
6 {0 Q( o. E' p& i" g' y        系统党委研究了很久,他们当然可以用两个进程来解决问题,一个进程负责和用户交互,另外一个进程负责自动保存,但是,这两个进程之间完全是独立的,每个人都有自己的一亩三分地(地址空间),完全互不知晓,进程之间通信的开销实在是太大,他们没有办法高效的操作那同一份文档数据。
. i7 ~% n! Q8 s" R3 K0 c% [3 U9 I5 o5 o; c# X
        后来还是劳模阿甘想出了一招:可以采用多进程的伟大思想啊!1 J% B# w' k: N+ U2 Z, I
- M* F1 _' a9 t+ l* K) T1 Q! j/ ?
        把一个进程当成一个资源的容器,让里边运行几个轻量级的进程,就叫线程吧,这些线程共享进程的所有资源,例如地址空间,全局变量,文件资源等等。
2 U" z6 V; ]  X+ Z( D1 ~
1 a* \! x+ r; m& s4 a' g        但是每个线程也有自己独特的部分,那就是要记住自己运行到哪一行指令了,有自己的函数调用堆栈,自己的状态等等,总而言之,就是为了能像切换进程那样切换线程。  C5 i, _, V& S7 L% S7 [$ @) {9 C8 m

8 L8 P' O$ ?, v4 @; i9 Y. A6 P
一个进程的自述 1-进程.jpg
* L& M4 b0 d  Q9 I! ?5 C+ Z
        拿我那个哥们的情况来说,一个进程保存着文档的数据,进程中有两个线程,一个负责和用户交互,另外一个专门负责定时的自动保存,IO导致的阻塞就不会影响另外一个了。
1 y6 F, K6 p* t* Z* m% v6 E+ X$ c' \$ `1 h6 g& A
        注意,这两个线程都能访问进程的所有东西,他们两个要小心,不要发起冲突才好--这是人类程序员要做的事情了,不归我们管。
1 A9 V: m0 z7 D* |8 z. w9 y+ K9 J3 F0 B4 ~; s
争 吵
, B  Y! |+ {) C* e+ f  R- U
        阿甘的建议被采纳了,其实这几乎是唯一的解决问题方式了,但是由谁来管理引起了激烈争吵。
9 F- q, D1 D& m, ?9 ?  P3 ~, Z1 k4 L. e
        系统党委有一波人坚持要在用户空间实现线程,换通俗的话说就是让那些进程在自个儿内部去管理线程,他们的理由也很充分:你们自己实现了线程,可以自己定制自己的调度算法,多灵活啊;, W' H& S0 c/ E0 P3 N! A
* w2 E9 P( R3 `" D# O! Q1 J) s
        所有的线程切换都在进程内完成,不用请求我们操作系统内核来处理,效率多高啊;/ @9 C" A$ y3 ~/ d5 j8 K- n
4 n8 l( K5 M( k4 ~* E' e' @" y
        况且你们可以在那些内核不支持线程的操作系统中运行,移植性多好啊。
, }% L  a3 ?4 g5 D2 h3 M2 H' r( I- A, t1 Q" w
一个进程的自述 2-进程.png
3 H, D4 z+ ^/ T" U( n
        我们清楚的知道这是内核想做甩手掌柜,因为他们选择性的忽略了一个致命的问题:如果由我们实现线程,则操作系统内核还是认为我们只是一个进程而已,对里边的线程一无所知,对进程的调度还是以进程为最小单位。
8 H2 w' d& H$ f0 j
+ j+ M  K1 m, B, q% W        一旦出现阻塞的系统调用,不仅仅阻塞那个线程,还会阻塞整个进程!" L8 a4 J) {% f3 g- A3 i

1 R( L5 J6 R: J1 e% F* R        例如文字处理器那个进程,如果负责定时保存的线程发起了IO调用,内核会认为,这是由进程发起的,于是就把整个进程给挂起了,虽然和用户交互的进程还是可以运行,也被强制的随着进程挂起来,不响应了,这多么悲催啊,又回到了老问题上去了。
0 s9 I3 Q; _9 x
: g. t' [: K5 ^2 p1 n/ {        所以我们坚决不能答应,我们则一致的要求:在内核中实现线程!内核需要知道进程中线程的存在,内核需要维护线程表,并且负责调度!
! s- n1 [. n: k7 ?* Z
/ h9 ~3 _$ L6 O' Y/ n
一个进程的自述 3-进程.png

+ o* j* Y/ e! D) A% a! O+ k        党委的人傲慢的说:你们不嫌累吗,每次创建一个线程都得通过我们内核,多慢啊。
( a# O* Z, ?$ s
& e+ a/ R; f4 b( B# {        我们说:只有这样,一个线程的IO系统调用才不会阻塞我们整个进程啊,你们完全可以选择同一个进程的另外一个线程去执行。
7 A. A: X# V& w. A
) V# N) [) y: Q: s        双发僵持不下,最后只好妥协,那就是:混合着实现吧。
* m5 m+ i" d9 T) O# ^  q  k8 E- ^6 C+ L% W! e
        用户空间的进程可以创建线程(用户线程),内核也会创建线程(内核线程),用户线程映射到内核线程上。* v  F2 i9 Z7 |3 @

  M* f6 E: [9 o: E% `! y& S9 N
一个进程的自述 4-进程.jpg
- m! `, D! Z4 h, E& o; ]! {" F
        问题基本解决了,但也带来了新的问题,我们的系统也变的越来越复杂,尤其是进程之间的通信和线程之间的同步,会那些程序员们带来无穷无尽的烦恼,这是后话了,有机会下次再说吧。. ?% q1 T. r. R+ X1 r9 r$ D0 M
& Z9 Y# l4 G1 _
上一篇
下一篇

评分

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

查看全部评分


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

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

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

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

你们有见过这么整齐的十五个字吗, b) b9 E5 R; N* C9 p+ b! a
这么整齐的十五个字人家最喜欢了5 `- h! m' v2 Y! i0 b
他们都说打出十五字才是最标准的
0 t: t' V- k! w我也没办法因为我要打十五个字啊
) x- ~% {: R) N2 n我说了多少次了不要只打十五个字2 n& y# R0 a8 a
你们那些十五字神马的完全弱爆了
8 a8 l3 u; T3 o2 O+ d9 b都怪吧主删我贴所以我只能到处逛( a# C: A; W% g& }. l
为了经验我没办法只能遇贴就灌水
9 v+ H& n( ^6 g9 R, k( K" n灌水也要讲技术保证句句是十五字
7 I# J3 P: d+ n' P0 l& g# d/ W如今发帖有困难整不好就被删贴了
' J7 r8 N  a9 p+ L我也没办法吧主他老是删我帖子啊. ~% N2 r6 ~' O; |7 b3 ]# W
只能够这样用十五字来混混经验了7 H' S/ x  D$ c) P3 L! e$ R* o. J
用十五字混经验的有谁比我厉害呢
+ N' A& r7 D2 H有前排就要占没前排也要灌一下水
/ u5 J" z1 F! ?& P6 u3 ~5 J3 b! i有前排不占或者不灌水是会后悔的
$ V- }8 C- S& L6 `4 H& M* j无论是多么无聊的帖子我都会去的
+ r! ^9 N+ P4 e+ O0 U因为为了一句话万一这贴子火了呢
4 l. b0 y/ h5 e% p/ y句句十五个字有哪个高手能超越呢( Q9 T5 |, I, m) e- @
#367:
深海里的那抹蓝 「龙战于野」 2018-1-20 23:45 来自手机 |显示全部楼层

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

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

本版积分规则

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

GMT+8, 2021-10-17 05:57 , Processed in 0.029712 second(s), 25 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表