登陆 / 注册 搜索

USERCENTER

站内搜索引擎

查看:4509| 回复: 3
打印 上一主题 下一主题

一个进程的自述

[复制链接]
跳转到指定楼层
楼主
仗剑天涯吾是土豪 发表于 2017-7-2 13:21:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
        我听说我的祖先,一生只能帮助人类做一件事,如果你想在这些专用“计算机”上干点别的事儿,例如安装个游戏玩玩,那是绝对不可能的,除非你把它拆掉,然后建一个全新的机器。而我这些祖先们勉强可以称为“程序”。
/ e6 Y, J+ b4 R3 r( r  v; x/ }4 d$ @( r# V+ r9 z/ t8 ]
        后来有个叫冯诺依曼的人,非常了不起,他提出了“存储程序”的思想,并且把计算机分为五大部件:运算器、控制器、存储器、输入设备、输出设备。
- z& Z+ C. I1 q2 i4 E
* Z1 E* {+ p! Q% b        各种各样不同功能的程序写好以后,和程序使用的数据一起存放在计算机的存储器中,即“存储程序”;然后,计算机按照存储的程序逐条取出指令加以分析,并执行指令所规定的操作。2 R7 u& V  f& o0 K

0 v8 O1 M- \, R& T7 M9 {3 g' S' K
 Life-of-process-visual3.jpg 一个进程的自述
# |+ |2 C6 N! y9 y/ r" W7 H- `
        这样一来,原来的专用计算机变成了通用的计算机,不管你是计算导弹弹道的,模拟核爆炸的,还是计算个人所得税的,统统都可以在一台机器上运行,我就是其中的一员:专门计算员工的薪水。7 ^9 B* {% r" ?7 i
* _% V: t6 {$ q
进 程 的 诞 生

. U  ^7 y! S' T        我所在的计算机是个批处理系统,每次上机时,我和其他程序都排好队,一个接一个的进入内存运行。1 L# F1 h2 x6 c3 P) g7 B& l

: ?$ Z1 H* w0 m. a0 m4 |        每个月末是发薪日,我都要运行一次,这样我每月都能见一次CPU阿甘,这个沉默寡言,但是跑的非常快的家伙。我知道内存看阿甘不顺眼,还告了它一状,说他一遇到IO操作的时候,就歇着喝茶,从来不管不问内存和硬盘的忙的要死的惨境。: ~+ S5 j) e0 Y; _+ Z' k+ z5 V
/ v, w& E; c4 f8 _
        其实我倒是觉得挺好,这时候正好和阿甘海阔天空的聊天,他阅程序无数,知道很多内部消息,每一个字节都清清楚楚,和他聊天实在是爽。
2 H; s  b* K" y# d/ H9 e$ }
- s0 L6 T; Y8 K' N        又到了月末发薪水的时候,我刚一进入内存,便看到这么一个公告:* ]. s9 N. \6 w
- b* N  h0 b7 p; m/ b$ Y* J9 o# `
        公告$ G, C9 j7 T- I* A9 U
        为了创建和谐社会,促进效率和公平,充分发挥每一个人的能力,经系统党委慎重研究决定:本系统自即日起,正式从“批处理系统”转为“多道程序系统”,希望各部门通力配合,一起完成切换工作。  d9 {2 c5 s* K& Q
        系统党委0 H% ~/ r- ?( q/ w7 A( K. `; Y9 n( g7 m  w
        xxxx年xx月xx日; Q# I/ {7 M* b% L

! X* A$ P5 q, i$ w5 T* D' T* V        我正想着啥是多道程序系统,阿甘便打电话给内存要我的指令开始运行了。和之前一样,运行到了第13869123行,这是个IO指令,我欢天喜地的准备和阿甘开聊了。5 ~0 l1 j4 U& f8 u) S: i

6 t5 O" Z' m4 @' ~7 Z& H4 {        阿甘说:哥们,准备保存现场吧,我要切换到另外一个程序来运行啦!" W  g6 d+ H; q4 D! O; O0 E% `
. `2 a2 `. P* v7 p
        “啊?我这正运行着呢!咱们不喝茶了?
% N2 Y1 N. w( F+ R* C% F- G  M4 u" Y
        “喝啥茶啊,马上另外一个程序就来了!”
' |8 @' ^0 e% q6 D2 ^: U6 E# Z5 b) l+ C/ g/ ]1 @% r. v
        "那我什么时候回来再见你?”我问道。
% x: J$ U4 ?( s! j: n
$ p5 o' T* T, M1 A7 \9 s( E$ c        “等这个IO指令完成,然后操作系统老大会再给你机会运行的。”
1 k) n6 g( h+ c0 k; q0 o) ~6 c! [' t/ o% p1 `$ a- H7 Y( N4 X& `
        “那谁来记住我当前正在运行第13869123行?还有刚把两个数据从内存装载到了你的寄存器,就是那个EAX,EBX,你一切换岂不都丢了?”我有点着急。
* H# I" m" Q8 l5 ^+ G  f. k) k0 U1 v& p
        阿甘说:“所以要暂时保存起来啊,不仅仅是这些,还有你的那些函数在调用过程中形成的栈帧和栈顶,我这里用寄存器EBP和ESP维护着,都得保存起来。”
$ i7 o* {6 I6 k. P9 u1 _* K9 E6 s( o
        “还有”阿甘接着说,“你打开的文件句柄,你的程序段和数据段的地址,你已经使用CPU的时间,等待CPU的时间。。。。。。以及其他好多好多的东西,统统都要保存下来。”, V* p3 ]% n8 e
% ?9 c/ h: i  w* K/ j4 ~+ |2 z
        我瞪大了眼睛:“这也太麻烦了吧,原来我只需要关心我的指令和数据,现在还得整这么多稀奇古怪的东西”
% d; x$ i$ P6 q; l: M3 Y8 ^7 h, d+ a" u- z/ Z
        “没办法,这就叫做上下文切换,把你的工作现场保存好,这样下一次运行的时候才能恢复啊。对了,老大给你们统一起了一个新的名称:进程!刚才那些需要保存的东西叫做叫做进程控制块(Processing Control Block,PCB),”
# B( I: l5 [: N3 _( J
0 t6 m& ?& r( I/ G4 Q        我想了想,这个名字还挺贴切的,一个真正进行的程序!只是这个正在进行的程序随时可以被打断啊。
; K2 _3 Y2 o: Z2 o9 k! L7 d6 U6 `" ~% _
        我只好保存好上下文,撤出CPU,回到内存里歇着去了,与此同时另外一个程序开始占据CPU运行。
9 R2 ]$ F7 f1 c1 q$ h
7 b. D4 X4 K$ ~) o/ K* i2 s# r) ^        其实我这个程序,奥,不对,我这个进程被放到一个阻塞队列里,等到IO的数据来了以后,又被赶到了就绪队列中,最后才有机会再次运行,再次见到CPU阿甘。
4 r- W# B' O5 G; {& x
& A% |- B6 N. T8 a        //进程的就绪,阻塞,运行这三个状态的转换和《一个线程的自白》中描述的非常类似。
7 E% r$ L# y( u2 M' }. t/ x' \% L/ ^  ]$ R
        阿甘从我的PCB中取出各种保存的信息,恢复了运行时现场,可是忙活了好一阵,没办法,这就是程序切换必须要付出的代价。, U# U: n- [8 h9 i& a+ p+ g

- X0 u2 Z  L3 E" C# N        我有点同情阿甘了,从此以后,他很难再悠闲和和我们海阔天空,每时每刻都处于高速的奔跑中。#j319:: @% T, S7 q+ [% S

+ P0 F! s7 g" x/ r: F8 R        得益于阿甘的高速度,虽然在同一时刻只有一个程序在运行,但是有很多程序在短时间内不断的切换,在外界看来,似乎多个程序在同时执行。
7 G1 F( l4 F! ~4 p- N" c, K6 }  W0 [, y8 @  M& f0 z
        尤其是那些速度超慢的人类,他们开着电脑一边听歌,一边上网,一边QQ,很是自在,理所当然的认为这些程序就是同时在运行。岂不知阿甘是让音乐播放器上运行几十毫秒,然后打断,让浏览器进程运行几十毫秒,再打断,让QQ也运行几十毫秒,如此循环往复。#j334:0 c6 S' j9 J' \/ l' J* y" w: y

+ j) x' d! K: j! X+ h" r. B        唉,阿甘真是能者多劳啊,这个计算机系统也算是达到了我们党委的目标:兼顾了效率和公平。
) q8 W/ i0 N* O8 d& s' @/ p2 f1 N8 c7 W+ m6 R  t4 U
线 程

- K6 K& d7 H6 {! s# ?5 l        有了进程就万事大吉了吗?人类的欲望是无止境的,很快就出现了新情况,举个例子来说吧,我有一个兄弟,是个文字处理软件,他和我不一样,他有界面,人类在用的时候能看到,这实在是很幸福,不像我总是在背后默默工作,几乎无人知晓。- A' n5 M+ `9 i8 V
1 n* h$ u1 t# v/ ~! ]* z, j  w
        这哥们有个智能的小功能,就是在人类编辑文档的时候能自动保存,防止辛辛苦苦敲的文字由于断电什么的丢掉。0 e$ x; ?5 t8 l! j6 X: N0 ~% M

/ S5 ^9 Q7 E! T        可是这个功能导致了人类的抱怨,原因很简单,自动保存文字是和IO打交道,那硬盘有多慢你也知道,这个时候整个进程就被挂起了,给人类的感觉就是:程序死了,键盘和鼠标不响应了!无法继续输入文字,但是过一会儿就好了。2 w! }2 H) S+ t' t5 @. v

* K1 u5 }! P9 U; V6 q" q6 A        并且这种假死一会儿就会出现一次(每当自动保存的时候),让人不胜其烦。0 i7 K3 b* F: @+ s
7 g/ T8 ~: Q; A1 ^, g  U
        系统党委研究了很久,他们当然可以用两个进程来解决问题,一个进程负责和用户交互,另外一个进程负责自动保存,但是,这两个进程之间完全是独立的,每个人都有自己的一亩三分地(地址空间),完全互不知晓,进程之间通信的开销实在是太大,他们没有办法高效的操作那同一份文档数据。
# s4 R6 S' ^" d" H; i
( k3 N$ d  l- s, ~. i) ]$ ], J6 e) U        后来还是劳模阿甘想出了一招:可以采用多进程的伟大思想啊!* U2 U$ @; G; Y- P3 d4 a. M

; @4 l8 n' X# e5 U# J) {        把一个进程当成一个资源的容器,让里边运行几个轻量级的进程,就叫线程吧,这些线程共享进程的所有资源,例如地址空间,全局变量,文件资源等等。
5 E/ ~* s1 K$ U- |4 S
1 c" S* R  Q4 ]4 q/ k. [- Q( v        但是每个线程也有自己独特的部分,那就是要记住自己运行到哪一行指令了,有自己的函数调用堆栈,自己的状态等等,总而言之,就是为了能像切换进程那样切换线程。! S$ `0 M1 N; Z6 _6 x& M0 _

; v! E, X! i. |" U3 _2 F; b
 1-进程.jpg 一个进程的自述

' I- H6 l$ U; Z! S3 L) M6 M' T        拿我那个哥们的情况来说,一个进程保存着文档的数据,进程中有两个线程,一个负责和用户交互,另外一个专门负责定时的自动保存,IO导致的阻塞就不会影响另外一个了。
- u  j- g" m& j4 c. c. r' {0 z/ U0 d. |5 ~0 Y, \
        注意,这两个线程都能访问进程的所有东西,他们两个要小心,不要发起冲突才好--这是人类程序员要做的事情了,不归我们管。1 C6 d5 ~8 u9 y# J6 l
# A# _% O2 K- B0 m9 S
争 吵
( N( K  K! p2 U9 e
        阿甘的建议被采纳了,其实这几乎是唯一的解决问题方式了,但是由谁来管理引起了激烈争吵。
0 a$ l( ~/ {% b9 T; ^3 Z' a- }9 W- w  N" V' I) [4 p
        系统党委有一波人坚持要在用户空间实现线程,换通俗的话说就是让那些进程在自个儿内部去管理线程,他们的理由也很充分:你们自己实现了线程,可以自己定制自己的调度算法,多灵活啊;3 ~/ ]3 x1 l; M9 A' T6 E: T

0 y# k  H4 m0 J3 W7 Y        所有的线程切换都在进程内完成,不用请求我们操作系统内核来处理,效率多高啊;
. g! M: ]% o8 t- L! Z. y
  }% P' \$ D* w! Y: J        况且你们可以在那些内核不支持线程的操作系统中运行,移植性多好啊。
% E7 |# v1 ]* M' W  q( G
7 a: g5 e, R2 _. U
 2-进程.png 一个进程的自述

, m! ~7 |- L. M' J8 ^        我们清楚的知道这是内核想做甩手掌柜,因为他们选择性的忽略了一个致命的问题:如果由我们实现线程,则操作系统内核还是认为我们只是一个进程而已,对里边的线程一无所知,对进程的调度还是以进程为最小单位。
7 s" W# r: M* C/ S) {9 M1 a+ [1 C
        一旦出现阻塞的系统调用,不仅仅阻塞那个线程,还会阻塞整个进程!
* x" {5 P& ?& K2 o: R+ b
+ o: u0 r5 F6 \) E& t5 p        例如文字处理器那个进程,如果负责定时保存的线程发起了IO调用,内核会认为,这是由进程发起的,于是就把整个进程给挂起了,虽然和用户交互的进程还是可以运行,也被强制的随着进程挂起来,不响应了,这多么悲催啊,又回到了老问题上去了。
$ y1 p& t1 ^( R' b; e4 y
$ q' c  v' h3 ~! n& A% E3 m  o* u) C& m        所以我们坚决不能答应,我们则一致的要求:在内核中实现线程!内核需要知道进程中线程的存在,内核需要维护线程表,并且负责调度!
) P0 u2 K" }$ E% e, ~/ l) o
# E' N7 }. V: }: D3 A: T
 3-进程.png 一个进程的自述
% @0 Y- `4 U" @: @
        党委的人傲慢的说:你们不嫌累吗,每次创建一个线程都得通过我们内核,多慢啊。2 O9 _3 m% |0 |8 i- ]2 I5 t0 v

( K0 T" _9 Z( U; k# g; j        我们说:只有这样,一个线程的IO系统调用才不会阻塞我们整个进程啊,你们完全可以选择同一个进程的另外一个线程去执行。: Z. f6 l! u5 V; L
0 f7 E# o5 I5 k
        双发僵持不下,最后只好妥协,那就是:混合着实现吧。( U% G4 _5 q* W, E; h9 G6 \
  S' n5 {$ G  F( L! l+ \
        用户空间的进程可以创建线程(用户线程),内核也会创建线程(内核线程),用户线程映射到内核线程上。+ z* Z& b- W; Q

% O& Y6 D* r; \. ~2 _
 4-进程.jpg 一个进程的自述

; {; Z" G3 ~# V; q8 \# ^! p        问题基本解决了,但也带来了新的问题,我们的系统也变的越来越复杂,尤其是进程之间的通信和线程之间的同步,会那些程序员们带来无穷无尽的烦恼,这是后话了,有机会下次再说吧。: X. A" Y8 b' c
' T4 q+ {6 F- V$ W" C2 Y/ e
上一篇:一块硬盘的自述摘要:我是一个非常精密的存储介质,虽然具有坚固冰 ...
下一篇:一块网卡的自述摘要:我知道我一生的使命就是传递信件,但有一个前提:我 ...

评分

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

查看全部评分

回复

使用道具 举报

巴黎环抱的花海出类拔萃 发表于 2017-8-31 19:20:57 来自手机 | 只看该作者
小白一个 顶一下
板凳
映画出类拔萃 发表于 2018-1-20 22:35:25 来自手机 | 只看该作者
你们有见过这么整齐的十五个字吗
5 `; ~5 {) d+ A& V这么整齐的十五个字人家最喜欢了- Y* O, F5 u! l- F: e- l
他们都说打出十五字才是最标准的
! q9 }: s2 `3 Z' |. C$ R# A我也没办法因为我要打十五个字啊/ g6 t4 N# M$ R* d# d* H
我说了多少次了不要只打十五个字& \) L: O9 {8 E' A
你们那些十五字神马的完全弱爆了2 F) q* ^' C- U7 G) W* r
都怪吧主删我贴所以我只能到处逛2 F7 z& c, [# h' c* {
为了经验我没办法只能遇贴就灌水2 a( z6 w  Y" R, D
灌水也要讲技术保证句句是十五字2 `0 w! x1 q: W
如今发帖有困难整不好就被删贴了
$ Y8 E+ Y1 L1 ~0 _: U我也没办法吧主他老是删我帖子啊8 S; M' E& _7 D
只能够这样用十五字来混混经验了6 q( S$ Y1 Q3 \; d5 c: {
用十五字混经验的有谁比我厉害呢
* z5 h/ M3 H' r有前排就要占没前排也要灌一下水
7 a0 T. ^2 |, @, h" ~) `$ N有前排不占或者不灌水是会后悔的
) E& q+ ]5 d9 _无论是多么无聊的帖子我都会去的
6 U2 _; C( Z/ x8 }0 a0 j( }  e因为为了一句话万一这贴子火了呢
" E" J5 N8 x0 e句句十五个字有哪个高手能超越呢
2 N' X; L9 {$ _" d#367:
地板
深海里的那抹蓝出类拔萃 发表于 2018-1-20 23:45:07 来自手机 | 只看该作者
尔等果如其母戏寡人欤?#y447:
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

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

GMT+8, 2019-6-25 03:58 , Processed in 0.120873 second(s), 40 queries , Redis On.

© 2015-2019 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表