等待,不是为了你能回来,而是找个借口不离开。 每日签到 收藏本站
登陆 / 注册 搜索

USERCENTER


查看:4674   回复: 3

一个进程的自述

[复制链接]
发新帖
跳转到指定楼层
楼主
仗剑天涯吾是土豪 发表于 2017-7-2 13:21:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

        我听说我的祖先,一生只能帮助人类做一件事,如果你想在这些专用“计算机”上干点别的事儿,例如安装个游戏玩玩,那是绝对不可能的,除非你把它拆掉,然后建一个全新的机器。而我这些祖先们勉强可以称为“程序”。
8 z1 Q; V# v* [: m5 \( D; P5 M- \2 y- Z# @) a: {) U
        后来有个叫冯诺依曼的人,非常了不起,他提出了“存储程序”的思想,并且把计算机分为五大部件:运算器、控制器、存储器、输入设备、输出设备。, n# c- i3 n+ N1 l. B8 a% b
9 D7 N; P6 i, I( J  ]
        各种各样不同功能的程序写好以后,和程序使用的数据一起存放在计算机的存储器中,即“存储程序”;然后,计算机按照存储的程序逐条取出指令加以分析,并执行指令所规定的操作。
, p8 d7 }7 i( i# K8 N
4 w! m6 ]; n' d1 b* J
 Life-of-process-visual3.jpg 一个进程的自述
, W) H% a5 ?3 x! y% Q' F
        这样一来,原来的专用计算机变成了通用的计算机,不管你是计算导弹弹道的,模拟核爆炸的,还是计算个人所得税的,统统都可以在一台机器上运行,我就是其中的一员:专门计算员工的薪水。% E* n4 d4 R' H0 ]. U) y$ f
- K" E6 @3 y+ j: A
进 程 的 诞 生
: U- u  B% x$ _# O7 [$ p% {
        我所在的计算机是个批处理系统,每次上机时,我和其他程序都排好队,一个接一个的进入内存运行。. U; q3 T, N/ \* n
4 B( r9 R) @+ Q) C2 f/ \
        每个月末是发薪日,我都要运行一次,这样我每月都能见一次CPU阿甘,这个沉默寡言,但是跑的非常快的家伙。我知道内存看阿甘不顺眼,还告了它一状,说他一遇到IO操作的时候,就歇着喝茶,从来不管不问内存和硬盘的忙的要死的惨境。5 `% y. Q/ P$ j: C. ^* ^
5 a3 \! h6 D. [, y/ e7 |. w2 W: l
        其实我倒是觉得挺好,这时候正好和阿甘海阔天空的聊天,他阅程序无数,知道很多内部消息,每一个字节都清清楚楚,和他聊天实在是爽。
4 Z$ c6 [  t7 N0 a: k
/ l; d) d" Q9 t5 B! u        又到了月末发薪水的时候,我刚一进入内存,便看到这么一个公告:
2 g1 N4 C0 r0 e/ c/ O$ d9 D. \. {% b5 `5 U9 v
        公告5 u3 X1 Z3 A; r$ Y
        为了创建和谐社会,促进效率和公平,充分发挥每一个人的能力,经系统党委慎重研究决定:本系统自即日起,正式从“批处理系统”转为“多道程序系统”,希望各部门通力配合,一起完成切换工作。
4 [, u0 @( b9 \# h. k        系统党委
( m* h& K  y+ l( I& k0 f6 u        xxxx年xx月xx日0 R. @. S: W, Q/ o  E" W& z
' J8 y8 I5 n  ^+ \* i7 {' \
        我正想着啥是多道程序系统,阿甘便打电话给内存要我的指令开始运行了。和之前一样,运行到了第13869123行,这是个IO指令,我欢天喜地的准备和阿甘开聊了。% j2 t2 [% t' D4 l( S5 a

1 E+ R: Z. U' |- a0 g        阿甘说:哥们,准备保存现场吧,我要切换到另外一个程序来运行啦!
$ e( B- L0 c% O) G# G; b( k6 @2 }) Q# f9 i# n! S8 A5 e% O
        “啊?我这正运行着呢!咱们不喝茶了?
6 l* I/ o4 e9 i$ ~" [% o, H4 v( f* q$ P7 r0 l1 c
        “喝啥茶啊,马上另外一个程序就来了!”% J7 J9 h. f+ C2 R* Q! r+ Q5 R

! H3 O0 {- {5 Z; i+ [% e        "那我什么时候回来再见你?”我问道。' ^, `' r: \3 O
  r1 x- r0 B3 o/ k. _. p1 V
        “等这个IO指令完成,然后操作系统老大会再给你机会运行的。”
- I; P3 N3 L6 w1 u; Q' K! W+ K' O* H( p" A- m9 M! e
        “那谁来记住我当前正在运行第13869123行?还有刚把两个数据从内存装载到了你的寄存器,就是那个EAX,EBX,你一切换岂不都丢了?”我有点着急。" D8 ^  L3 k' o' [5 C$ L! z

/ p4 N. h% c$ G9 i1 S2 \; ^        阿甘说:“所以要暂时保存起来啊,不仅仅是这些,还有你的那些函数在调用过程中形成的栈帧和栈顶,我这里用寄存器EBP和ESP维护着,都得保存起来。”3 i8 ^( k5 Q% `9 y0 _
5 b: d6 ^& j5 @5 u, k
        “还有”阿甘接着说,“你打开的文件句柄,你的程序段和数据段的地址,你已经使用CPU的时间,等待CPU的时间。。。。。。以及其他好多好多的东西,统统都要保存下来。”# j, e! y1 i2 |" R, \/ D: c% i

; N9 h2 h4 T  ]/ g% {3 v: e1 m        我瞪大了眼睛:“这也太麻烦了吧,原来我只需要关心我的指令和数据,现在还得整这么多稀奇古怪的东西”$ v' O8 w) L* O
( u# X/ }( K2 C4 t4 b
        “没办法,这就叫做上下文切换,把你的工作现场保存好,这样下一次运行的时候才能恢复啊。对了,老大给你们统一起了一个新的名称:进程!刚才那些需要保存的东西叫做叫做进程控制块(Processing Control Block,PCB),”
5 ?: ^0 d9 Z3 I% t. M6 p' R" |6 B" A, l1 ~" L9 n/ K6 X( F
        我想了想,这个名字还挺贴切的,一个真正进行的程序!只是这个正在进行的程序随时可以被打断啊。
: k, S: ?- K- C5 [* J
$ Y- p- i  F% r" ?! ?) I        我只好保存好上下文,撤出CPU,回到内存里歇着去了,与此同时另外一个程序开始占据CPU运行。
( a% t+ B- x  c
2 w% m4 \1 i# I4 D" s! V0 D5 c        其实我这个程序,奥,不对,我这个进程被放到一个阻塞队列里,等到IO的数据来了以后,又被赶到了就绪队列中,最后才有机会再次运行,再次见到CPU阿甘。( c) a: T3 j) H; }
9 Z: _8 h& W2 P& R4 @' c' W
        //进程的就绪,阻塞,运行这三个状态的转换和《一个线程的自白》中描述的非常类似。9 D3 ^3 [  W3 _& H' A
( u4 K% O0 j! ~% g$ a8 m  d
        阿甘从我的PCB中取出各种保存的信息,恢复了运行时现场,可是忙活了好一阵,没办法,这就是程序切换必须要付出的代价。( j2 a6 r3 U3 ~0 [
; e7 c* c0 v4 W5 V+ P# V' m
        我有点同情阿甘了,从此以后,他很难再悠闲和和我们海阔天空,每时每刻都处于高速的奔跑中。#j319:6 @2 z# M- g& ]- q
/ F" D. }0 z# U: x
        得益于阿甘的高速度,虽然在同一时刻只有一个程序在运行,但是有很多程序在短时间内不断的切换,在外界看来,似乎多个程序在同时执行。) x4 F, j' y( }) b% z

4 L& O5 [) A9 f! D! L# j        尤其是那些速度超慢的人类,他们开着电脑一边听歌,一边上网,一边QQ,很是自在,理所当然的认为这些程序就是同时在运行。岂不知阿甘是让音乐播放器上运行几十毫秒,然后打断,让浏览器进程运行几十毫秒,再打断,让QQ也运行几十毫秒,如此循环往复。#j334:
  e, t- ~- ^7 l' [! M4 a* }  ^
7 a5 m" ~! x* l/ y( ~4 o        唉,阿甘真是能者多劳啊,这个计算机系统也算是达到了我们党委的目标:兼顾了效率和公平。
, P$ g+ _% {! o. f. Q) e( y
$ ^: r% C4 A3 M; w% \
线 程

2 r* \1 |) X) C7 V( [% Y        有了进程就万事大吉了吗?人类的欲望是无止境的,很快就出现了新情况,举个例子来说吧,我有一个兄弟,是个文字处理软件,他和我不一样,他有界面,人类在用的时候能看到,这实在是很幸福,不像我总是在背后默默工作,几乎无人知晓。
3 Q0 `9 p9 z: D
1 Z, v/ E) d* ?8 x/ G/ |7 J; Z: s        这哥们有个智能的小功能,就是在人类编辑文档的时候能自动保存,防止辛辛苦苦敲的文字由于断电什么的丢掉。
. o" A" K7 h5 d" B4 r7 Q6 w1 |; m) U
        可是这个功能导致了人类的抱怨,原因很简单,自动保存文字是和IO打交道,那硬盘有多慢你也知道,这个时候整个进程就被挂起了,给人类的感觉就是:程序死了,键盘和鼠标不响应了!无法继续输入文字,但是过一会儿就好了。3 F) M7 N$ h& u7 U' t
% U) d7 n1 U3 z
        并且这种假死一会儿就会出现一次(每当自动保存的时候),让人不胜其烦。5 G* s% O" h8 `# b3 G
! A8 d( U7 _; D. U' d
        系统党委研究了很久,他们当然可以用两个进程来解决问题,一个进程负责和用户交互,另外一个进程负责自动保存,但是,这两个进程之间完全是独立的,每个人都有自己的一亩三分地(地址空间),完全互不知晓,进程之间通信的开销实在是太大,他们没有办法高效的操作那同一份文档数据。
- K6 B2 M6 U+ N/ k: S2 U# }, D$ ]  \. k
        后来还是劳模阿甘想出了一招:可以采用多进程的伟大思想啊!
" X& b: \. T) r& _) O5 Y/ U
+ D1 Y6 [$ z, Y9 G  o+ S        把一个进程当成一个资源的容器,让里边运行几个轻量级的进程,就叫线程吧,这些线程共享进程的所有资源,例如地址空间,全局变量,文件资源等等。. h/ A0 G. p4 E4 I

) {+ O$ D7 J1 {        但是每个线程也有自己独特的部分,那就是要记住自己运行到哪一行指令了,有自己的函数调用堆栈,自己的状态等等,总而言之,就是为了能像切换进程那样切换线程。: Q& @: e2 d' O- p0 R! l7 H
" ^' v6 ~6 B. q0 B# l9 o+ K( n5 Y- ?% F; v
 1-进程.jpg 一个进程的自述

; T! S. _( K- s1 q. m        拿我那个哥们的情况来说,一个进程保存着文档的数据,进程中有两个线程,一个负责和用户交互,另外一个专门负责定时的自动保存,IO导致的阻塞就不会影响另外一个了。; m# m% S: [3 M; I1 Q' _2 e  o

. X( x+ j# L& F/ ^+ R/ e2 R        注意,这两个线程都能访问进程的所有东西,他们两个要小心,不要发起冲突才好--这是人类程序员要做的事情了,不归我们管。! J; c; k! ]' p/ S
. Q4 h) l! {) t1 i( ?
争 吵
1 }% j; r4 _- N" P! u
        阿甘的建议被采纳了,其实这几乎是唯一的解决问题方式了,但是由谁来管理引起了激烈争吵。; T7 R. d4 S  n( P

& T8 E/ I* v- W! ~        系统党委有一波人坚持要在用户空间实现线程,换通俗的话说就是让那些进程在自个儿内部去管理线程,他们的理由也很充分:你们自己实现了线程,可以自己定制自己的调度算法,多灵活啊;
- \4 S! L" g4 h% Q
+ H4 h, @5 ~* u        所有的线程切换都在进程内完成,不用请求我们操作系统内核来处理,效率多高啊;
# _% j0 M% r3 @, v, q
9 ]" M6 U6 X" i7 e0 k5 s6 N) F& ^        况且你们可以在那些内核不支持线程的操作系统中运行,移植性多好啊。$ M) {9 X: v* K6 ?; m) C

4 I! M5 s" H- S: t4 j5 b1 I
 2-进程.png 一个进程的自述
7 N6 T: V; `4 r# E  u
        我们清楚的知道这是内核想做甩手掌柜,因为他们选择性的忽略了一个致命的问题:如果由我们实现线程,则操作系统内核还是认为我们只是一个进程而已,对里边的线程一无所知,对进程的调度还是以进程为最小单位。
3 k) O) D& s# [( M
6 I3 c" q& R' F1 ]        一旦出现阻塞的系统调用,不仅仅阻塞那个线程,还会阻塞整个进程!
- T3 V$ d+ ?9 r5 X! ^; W
: P; ~( s& ?! g- l9 }7 D, v5 X        例如文字处理器那个进程,如果负责定时保存的线程发起了IO调用,内核会认为,这是由进程发起的,于是就把整个进程给挂起了,虽然和用户交互的进程还是可以运行,也被强制的随着进程挂起来,不响应了,这多么悲催啊,又回到了老问题上去了。
2 z7 N$ Z6 \/ @3 R  u' ~2 U- k& H* \# P0 T' S, C- M+ R
        所以我们坚决不能答应,我们则一致的要求:在内核中实现线程!内核需要知道进程中线程的存在,内核需要维护线程表,并且负责调度!) U; C' l4 P6 O' |# D

. z* x! I7 `2 v1 z# d
 3-进程.png 一个进程的自述
! }! [5 u) }6 h: u
        党委的人傲慢的说:你们不嫌累吗,每次创建一个线程都得通过我们内核,多慢啊。+ q! P0 `: f* w& K2 L

8 Q0 Y8 [9 b9 b5 a$ i        我们说:只有这样,一个线程的IO系统调用才不会阻塞我们整个进程啊,你们完全可以选择同一个进程的另外一个线程去执行。
* t; m& R1 f/ @  t) T0 X. g, |+ b9 z" r6 K% N, j; X2 r
        双发僵持不下,最后只好妥协,那就是:混合着实现吧。
4 p  r  N3 O# _8 @
7 l7 A  F2 l* E0 A9 z; }        用户空间的进程可以创建线程(用户线程),内核也会创建线程(内核线程),用户线程映射到内核线程上。
9 k- g  G/ j$ M5 n) }+ y
; g% L, R: |+ P2 @5 P
 4-进程.jpg 一个进程的自述
, m6 X3 M, w9 `) j5 }( z8 R- H% Y
        问题基本解决了,但也带来了新的问题,我们的系统也变的越来越复杂,尤其是进程之间的通信和线程之间的同步,会那些程序员们带来无穷无尽的烦恼,这是后话了,有机会下次再说吧。
0 e5 Q1 T0 |0 b  }/ |1 n- P, b1 e# a! ?2 |  ?

上一篇:  一块硬盘的自述

下一篇:  一块网卡的自述

评分

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

查看全部评分

巴黎环抱的花海「出类拔萃」 发表于 2017-8-31 19:20:57 来自手机 | 只看该作者
小白一个 顶一下
映画「出类拔萃」 发表于 2018-1-20 22:35:25 来自手机 | 只看该作者
你们有见过这么整齐的十五个字吗0 u: {- S( x! O& T/ L- {+ ~# m
这么整齐的十五个字人家最喜欢了& U# ]; C: v# V
他们都说打出十五字才是最标准的
* w; @# J5 p2 x7 X! Y8 _9 h我也没办法因为我要打十五个字啊' s6 ]8 ]+ t- y8 ?& P( [% F4 E
我说了多少次了不要只打十五个字8 @2 z& A4 J# k0 S7 ^2 Y; C
你们那些十五字神马的完全弱爆了
/ R# f6 l2 d: J8 t都怪吧主删我贴所以我只能到处逛
  J8 Y7 \8 a2 S( v为了经验我没办法只能遇贴就灌水
3 N& j. G6 L' F: Z" W灌水也要讲技术保证句句是十五字
( |& M8 L- Y9 W) L如今发帖有困难整不好就被删贴了7 f2 b9 W/ x% ^2 I2 C0 q+ E- X
我也没办法吧主他老是删我帖子啊/ I: K! z  p* r2 U& ^
只能够这样用十五字来混混经验了) @$ [) ]8 y8 Z  t' [( V' G/ q$ @2 U
用十五字混经验的有谁比我厉害呢
1 P& @# T6 \: `' z$ f0 W0 r有前排就要占没前排也要灌一下水# X, _1 t: p% N! y6 M9 _
有前排不占或者不灌水是会后悔的
( h! o$ B% N- H4 U) z% \: b无论是多么无聊的帖子我都会去的% w! i6 G3 A! E' k) l
因为为了一句话万一这贴子火了呢
& N8 m7 p0 f2 m5 q' |* `句句十五个字有哪个高手能超越呢$ s, c: N4 c+ b8 {; a
#367:
深海里的那抹蓝「出类拔萃」 发表于 2018-1-20 23:45:07 来自手机 | 只看该作者
尔等果如其母戏寡人欤?#y447:
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

关于我们|小黑屋|手机版|Archiver|古黑论

GMT+8, 2019-8-26 13:45 , Processed in 0.043555 second(s), 32 queries , Gzip On, Redis On.

© 2015-2019 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表