到目前為止,你肯定已經(jīng)見過很多次這兩個詞了,“程序”“進程”。那程序和進程到底有什么區(qū)別呢。
程序是一個靜態(tài)的概念。
進程是一個動態(tài)的概念。
我們用一個例子來形象的講解一下這個區(qū)別。程序其實本質(zhì)上和我們的菜譜非常類似,一個菜譜規(guī)定了完成一道菜的整個流程,一步一步每個節(jié)點執(zhí)行什么樣的操作,但是看一遍菜譜是不能變出一道美味可口的菜肴的。要想真正做出一道菜就應該按照菜譜的要求走一遍,準備好食材,按照菜譜的指導,打開燃氣,鍋熱后倒入油,待油溫適宜后放入準備好的食材、調(diào)味料,然后不斷翻炒直至炒熟,這樣一道美味就新鮮出鍋啦。
在這個例子中 如果把菜譜比作我們寫的程序,那么按照菜譜真正炒菜的這個過程才是進程 。如果你自己真的炒過菜,相信會對此有更加深刻地的理解,如果你還沒有做過菜,那么筆者強烈建議讀者自己真正的去炒一道菜感受一下。
進程是計算機科學當中一個及其重要的概念,徹底理解進程是理解操作系統(tǒng)工作原理的關鍵所在,同時也是編程高手的標志之一。
編程高手與普通程序員的分水嶺
進程是計算機操作系統(tǒng)中至關重要的一個概念,可以說徹底理解進程這個概念是能否成為擁有“自我探索”能力的編程高手的一個分水嶺, 能徹底理解操作系統(tǒng)如何實現(xiàn)進程是編程高手的關鍵性標志。 理解了這個概念以后你幾乎不會再遇到程序出現(xiàn)了問題,但是你根本就不知道到底哪里出現(xiàn)問題的窘境。正因為這個概念的重要性因此我們后面的文章會有很大一部分都是圍繞著進程來進行講解的,目的就是確保大家能真正掌握這一思想,從而在成為高手的道路上邁出堅實的一步。
接下來讓我們首先來看一下程序是如何生成的。
程序是如何生成的
程序這個詞其實是比較籠統(tǒng)的,在我們學習工作工作過程中,即指我們?nèi)祟惪梢哉J識的字符串程序,也可以指機器可以運行的二進制機器指令程序,這個程序就是可執(zhí)行程序。
所以在這里需要大家能意識到一點,程序這個詞有兩種含義:
- 人類可以認識的程序,這些程序就是用比如C/C++,Java,Python語言寫成的文本文件。比如helloworld.c,hellworld.java,helloworld.py
- 機器可以認識的程序,這些程序就是可執(zhí)行程序。Windows下就是exe程序,Linux下就是elf程序。
因為計算機看不懂人類可以認識的文本文件程序,因此需要將文本文件程序轉(zhuǎn)換為機器可以認識的可執(zhí)行程序。這個翻譯過程就是編譯器來完成的。編譯器將文本文件程序翻譯成二進制機器指令程序。
在前幾節(jié)中,有兩種類型的語言,一類是C/C++這種編譯型語言,一類是比如Python、Java等解釋型語言,CPU可以直接運行C/C++程序經(jīng)編譯后生成的機器指令,但解釋型語言不能直接被CPU執(zhí)行,解釋型語言是被解釋器直接執(zhí)行的,而解釋器可以被CPU直接執(zhí)行,因為這些解釋器通常都是C/C++語言編寫的,就好比下面這樣:
$ python helloworld.py
其中python就是一個C語言程序,只不過這個C語言程序可以來執(zhí)行python程序。有了這些背景后,接下來我們重點關注C/C++這類解釋型語言是如何從文本文件轉(zhuǎn)變?yōu)榭蓤?zhí)行文件的。
接下來的這句話,大家一定要理解,那就是:
“ 程序其實包含兩部分內(nèi)容,一部分是指令(代碼),另一部分是數(shù)據(jù) ”
有的同學可能會問了,程序里面不都是“指令(代碼)”嗎,不是的,大家一定要意識到這一點,非常重要。程序中不都是指令(代碼),還包括數(shù)據(jù)。
比如 int a = 100; 這段代碼在生成的可執(zhí)行程序中是沒有對應的機器指令的,為什么,因為這是數(shù)據(jù)。那么什么樣的代碼才有對應的可執(zhí)行程序呢?比如if... while... +-*/,return等語句才會有對應的機器指令。
現(xiàn)在你應該清楚了吧,一般來說,對數(shù)據(jù)的操作部分我們都可以認為是指令,而除此之外的定義都是數(shù)據(jù)。
有了這些知識,你就能理解編譯器啦,編譯器的工作就是把C程序中的對數(shù)據(jù)的操作部分翻譯成二進制機器指令,這些指令統(tǒng)一放在二進制文件中的一部分,這一部分就叫代碼段,然后編譯器收集C程序中定義的數(shù)據(jù),把這些數(shù)據(jù)統(tǒng)一放在二進制文件中的另一部分,這一部分就叫數(shù)據(jù)段,就好比披薩一樣分為兩層,一個可執(zhí)行文件就如下圖所示:
這就是為什么最終可執(zhí)行文件中有兩部分的原因,這也是可執(zhí)行程序在磁盤中的看起來是樣子的。
這里需要大家意識到的一點就是可執(zhí)行程序也是一個保存在磁盤上的普通文件,和我們的經(jīng)常使用的文本文件沒有本質(zhì)的區(qū)別。
我們來總結一下,編譯器將源代碼分成兩類,一類是對數(shù)據(jù)的操作,這一部分就被編譯器翻譯成了機器指令;另一類是數(shù)據(jù),這些數(shù)據(jù)被編譯器收集后放到了可執(zhí)行文件的數(shù)據(jù)段。
可執(zhí)行程序也是文件,和普通的文本文件沒有什么本質(zhì)的區(qū)別,只不過文本文件中保存的是人類認識的字符,而可執(zhí)行程序保存的是機器指令以及機器指令操作的數(shù)據(jù),這些二進制的指令或數(shù)據(jù)人類是很難直觀理解的,但是CPU不一樣,CPU可以直接執(zhí)行這些二進制機器指令。
現(xiàn)在你應該清楚程序是如何生成的了吧,程序是編譯器翻譯而成的,可執(zhí)行程序和普通文件一樣,生成后被安靜的保存在磁盤上。
從這里我們也可以看出程序其實和菜譜一樣是一個靜態(tài)的概念。程序被保存在磁盤上,只要磁盤沒被破壞程序就可以一直被保存下去。
接下來讓我們看看進程是怎么來的。
進程是如何生成的
到目前為止,保存在磁盤上的可執(zhí)行程序和操作系統(tǒng)還沒有半毛錢關系。如果一個程序僅僅是放在磁盤上除了占用磁盤控制之外其實是沒有任何用處的,只有程序運行起來才能真正發(fā)揮它的作用。
那么程序是如何被運行起來的呢?
這點大家應該都非常熟悉,在Windows中我們通過雙擊程序圖標,在Linux下直接鍵入程序的名字。但是這個回答大家可能并不滿意,因為計算機的角度上看我們依然不清楚程序是如何運行起來的。
要回答這個問題,就需要我們的主角登場了,這里的主角就是操作系統(tǒng)。
我們的程序?qū)嶋H上是被操作系統(tǒng)運行起來的,大體經(jīng)過了以下幾個階段。
1,當我們雙擊程序圖標或者鍵入程序名字后,操作系統(tǒng)根據(jù)程序的名字去磁盤中找到可執(zhí)行程序。
2,操作系統(tǒng)在內(nèi)存為即將要運行的程序劃出一塊區(qū)域。
3,操作系統(tǒng)將找到的可執(zhí)行程序從磁盤中copy到剛剛劃分出的內(nèi)存區(qū)域當中。
4,操作系統(tǒng)在內(nèi)存中找到可執(zhí)行程序代碼段的起始位置,假設這個地址是A。
5,操作系統(tǒng)告訴CPU從A這個位置開始執(zhí)行。
經(jīng)過了這幾個步驟后,CPU就開始運行我們的程序啦。值得注意的是以上只簡化后的幾個重要步驟,實際情況要更加復雜,但是這個簡化的步驟已經(jīng)足以讓我們理解操作系統(tǒng)是如何來運行程序的了。在后面的文章中我們會詳細描述這一過程。所以你會看到當打開一個比較大的程序,比如游戲時,總是非常慢,還會給出“正在加載”的提示,其實就是操作系統(tǒng)在忙著以上幾個步驟。
在這里,我們可以給出進程的定義了。
程序運行起來之后就叫進程。
而進程也是我們后面文章的重中之重。
進程是操作系統(tǒng)精心構筑的一個概念,理解進程對理解操作系統(tǒng)來說至關重要,同時深刻理解進程也是編程高手和普通程序員的分水嶺。
總結
在這一節(jié)中我們重點關注了程序和進程這兩個概念。
程序是靜態(tài)的,放在磁盤上的,保存了程序的指令和數(shù)據(jù)普通文件。
進程是動態(tài)的,存防在內(nèi)存中的,CPU執(zhí)行程序時的樣子。
只要磁盤沒有被破壞,程序就可以永久保存。
而進程一旦在內(nèi)存中被CPU執(zhí)行完畢,操作系統(tǒng)就會回收進程占據(jù)的所有內(nèi)存空間,進程的生命周期取決于程序的運行時間。
程序需要存放在磁盤上,占用的是磁盤的空間。
而進程需要在內(nèi)存中被運行,占用的是內(nèi)存空間。
-
操作系統(tǒng)
+關注
關注
37文章
6703瀏覽量
123151 -
程序
+關注
關注
116文章
3767瀏覽量
80786 -
進程
+關注
關注
0文章
201瀏覽量
13941
發(fā)布評論請先 登錄
相關推薦
評論