15Linux 基礎入門--Linux 進程概念

Linux 進程概念

概念的理解

首先程序與進程是什么酪穿?程序與進程又有什么區(qū)別嫌蚤?
程序(procedure):不太精確地說摊灭,程序就是執(zhí)行一系列有邏輯、有順序結構的指令,幫我們達成某個結果辟拷。就如我們?nèi)ゲ宛^撞羽,給服務員說我要牛肉蓋澆飯,她執(zhí)行了做牛肉蓋澆飯這么一個程序衫冻,最后我們得到了這么一盤牛肉蓋澆飯诀紊。它需要去執(zhí)行,不然它就像一本武功秘籍隅俘,放在那里等人翻看邻奠。
進程(process):進程是程序在一個數(shù)據(jù)集合上的一次執(zhí)行過程,在早期的 UNIX为居、Linux 2.4 及更早的版本中碌宴,它是系統(tǒng)進行資源分配和調(diào)度的獨立基本單位。同上一個例子蒙畴,就如我們?nèi)チ瞬宛^唧喉,給服務員說我要牛肉蓋澆飯,她執(zhí)行了做牛肉蓋澆飯這么一個程序忍抽,而里面做飯的是一個進程八孝,做牛肉湯汁的是一個進程,把牛肉湯汁與飯混合在一起的是一個進程鸠项,把飯端上桌的是一個進程干跛。它就像是我們在看武功秘籍這么一個過程,然后一個篇章一個篇章地去練祟绊。
簡單來說楼入,程序是為了完成某種任務而設計的軟件,比如 vim 是程序牧抽。什么是進程呢嘉熊?進程就是運行中的程序。

程序只是一些列指令的集合扬舒,是一個靜止的實體阐肤,而進程不同,進程有以下的特性:
動態(tài)性:進程的實質(zhì)是一次程序執(zhí)行的過程讲坎,有創(chuàng)建孕惜、撤銷等狀態(tài)的變化。而程序是一個靜態(tài)的實體晨炕。
并發(fā)性:進程可以做到在一個時間段內(nèi)衫画,有多個程序在運行中。程序只是靜態(tài)的實體瓮栗,所以不存在并發(fā)性削罩。
獨立性:進程可以獨立分配資源瞄勾,獨立接受調(diào)度,獨立地運行弥激。
異步性:進程以不可預知的速度向前推進丰榴。
結構性:進程擁有代碼段、數(shù)據(jù)段秆撮、PCB(進程控制塊,進程存在的唯一標志)换况。也正是因為有結構性职辨,進程才可以做到獨立地運行。

并發(fā):在一個時間段內(nèi)戈二,宏觀來看有多個程序都在活動舒裤,有條不紊的執(zhí)行(每一瞬間只有一個在執(zhí)行,只是在一段時間有多個程序都執(zhí)行過)
并行:在每一個瞬間觉吭,都有多個程序都在同時執(zhí)行腾供,這個必須有多個 CPU 才行

引入進程是因為傳統(tǒng)意義上的程序已經(jīng)不足以描述 OS 中各種活動之間的動態(tài)性、并發(fā)性鲜滩、獨立性還有相互制約性伴鳖。程序就像一個公司,只是一些證書徙硅,文件的堆積(靜態(tài)實體)榜聂。而當公司運作起來就有各個部門的區(qū)分,財務部嗓蘑,技術部须肆,銷售部等等,就像各個進程桩皿,各個部門之間可以獨立運作豌汇,也可以有交互(獨立性、并發(fā)性)泄隔。
而隨著程序的發(fā)展越做越大拒贱,又會繼續(xù)細分,從而引入了線程的概念佛嬉,當代多數(shù)操作系統(tǒng)柜思、Linux 2.6 及更新的版本中,進程本身不是基本運行單位巷燥,而是線程的容器赡盘。就像上述所說的,每個部門又會細分為各個工作小組(線程)缰揪,而工作小組需要的資源需要向上級(進程)申請陨享。

線程(thread)是操作系統(tǒng)能夠進行運算調(diào)度的最小單位葱淳。它被包含在進程之中,是進程中的實際運作單位抛姑。一條線程指的是進程中一個單一順序的控制流赞厕,一個進程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務定硝。因為線程中幾乎不包含系統(tǒng)資源皿桑,所以執(zhí)行更快、更有效率蔬啡。

簡而言之诲侮,一個程序至少有一個進程,一個進程至少有一個線程箱蟆。線程的劃分尺度小于進程沟绪,使得多線程程序的并發(fā)性高。另外空猜,進程在執(zhí)行過程中擁有獨立的內(nèi)存單元绽慈,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率辈毯。就如下圖所示:


image.png

進程的屬性

進程的分類

大概明白進程是個什么樣的存在后坝疼,我們需要進一步了解的就是進程分類∽晃郑可以從兩個角度來分:
以進程的功能與服務的對象來分裙士;
以應用程序的服務類型來分;

第一個角度來看管毙,我們可以分為用戶進程與系統(tǒng)進程:
用戶進程:通過執(zhí)行用戶程序腿椎、應用程序或稱之為內(nèi)核之外的系統(tǒng)程序而產(chǎn)生的進程,此類進程可以在用戶的控制下運行或關閉夭咬。
系統(tǒng)進程:通過執(zhí)行系統(tǒng)內(nèi)核程序而產(chǎn)生的進程啃炸,比如可以執(zhí)行內(nèi)存資源分配和進程切換等相對底層的工作;而且該進程的運行不受用戶的干預卓舵,即使是 root 用戶也不能干預系統(tǒng)進程的運行南用。

第二角度來看,我們可以將進程分為交互進程掏湾、批處理進程裹虫、守護進程:
交互進程:由一個 shell 終端啟動的進程,在執(zhí)行過程中融击,需要與用戶進行交互操作筑公,可以運行于前臺,也可以運行在后臺尊浪。
批處理進程:該進程是一個進程集合匣屡,負責按順序啟動其他的進程封救。
守護進程:守護進程是一直運行的一種進程,在 Linux 系統(tǒng)啟動時啟動捣作,在系統(tǒng)關閉時終止誉结。它們獨立于控制終端并且周期性的執(zhí)行某種任務或等待處理某些發(fā)生的事件。例如 httpd 進程券躁,一直處于運行狀態(tài)惩坑,等待用戶的訪問。還有經(jīng)常用的 cron(在 centOS 系列為 crond)進程也拜,這個進程為 crontab 的守護進程以舒,可以周期性的執(zhí)行用戶設定的某些任務。

進程的衍生

進程有這么多的種類搪泳,那么進程之間定是有相關性的,而這些有關聯(lián)性的進程又是如何產(chǎn)生的扼脐,如何衍生的岸军?
就比如我們啟動了終端,就是啟動了一個 bash 進程瓦侮,我們可以在 bash 中再輸入 bash 則會再啟動一個 bash 的進程艰赞,此時第二個 bash 進程就是由第一個 bash 進程創(chuàng)建出來的,他們之間又是個什么關系肚吏?
我們一般稱呼第一個 bash 進程是第二 bash 進程的父進程方妖,第二 bash 進程是第一個 bash 進程的子進程,這層關系是如何得來的呢罚攀?

關于父進程與子進程便會提及這兩個系統(tǒng)調(diào)用 fork() 與 exec()
fork-exec是由 Dennis M. Ritchie 創(chuàng)造的
fork() 是一個系統(tǒng)調(diào)用(system call)党觅,它的主要作用就是為當前的進程創(chuàng)建一個新的進程,這個新的進程就是它的子進程斋泄,這個子進程除了父進程的返回值和 PID 以外其他的都一模一樣杯瞻,如進程的執(zhí)行代碼段,內(nèi)存信息炫掐,文件描述魁莉,寄存器狀態(tài)等等
exec() 也是系統(tǒng)調(diào)用,作用是切換子進程中的執(zhí)行程序也就是替換其從父進程復制過來的代碼段與數(shù)據(jù)段

子進程就是父進程通過系統(tǒng)調(diào)用 fork() 而產(chǎn)生的復制品募胃,fork() 就是把父進程的 PCB 等進程的數(shù)據(jù)結構信息直接復制過來旗唁,只是修改了 PID,所以一模一樣痹束,只有在執(zhí)行 exec() 之后才會不同检疫,而早先的 fork() 比較消耗資源后來進化成 vfork(),效率高了不少祷嘶,感興趣的同學可以查查為什么电谣。
這就是子進程產(chǎn)生的由來秽梅。簡單的實現(xiàn)邏輯就如下方所示:

pid_t p;

p = fork();
if (p == (pid_t) -1)
        /* ERROR */
else if (p == 0)
        /* CHILD */
else
        /* PARENT */

既然子進程是通過父進程而衍生出來的,那么子進程的退出與資源的回收定然與父進程有很大的相關性剿牺。當一個子進程要正常的終止運行時企垦,或者該進程結束時它的主函數(shù) main() 會執(zhí)行 exit(n); 或者 return n,這里的返回值 n 是一個信號晒来,系統(tǒng)會把這個 SIGCHLD 信號傳給其父進程钞诡,當然若是異常終止也往往是因為這個信號。
在將要結束時的子進程代碼執(zhí)行部分已經(jīng)結束執(zhí)行了湃崩,系統(tǒng)的資源也基本歸還給系統(tǒng)了荧降,但若是其進程的進程控制塊(PCB)仍駐留在內(nèi)存中,而它的 PCB 還在攒读,代表這個進程還存在(因為 PCB 就是進程存在的唯一標志朵诫,里面有 PID 等消息),并沒有消亡薄扁,這樣的進程稱之為僵尸進程(Zombie)剪返。
如圖中第四列標題是 S,S 表示的是進程的狀態(tài)邓梅,而在下屬的第三行的 Z 表示的是 Zombie 的意思脱盲。( ps 命令將在后續(xù)詳解)


image.png

正常情況下,父進程會收到兩個返回值:exit code(SIGCHLD 信號)與 reason for termination 日缨。之后钱反,父進程會使用 wait(&status) 系統(tǒng)調(diào)用以獲取子進程的退出狀態(tài),然后內(nèi)核就可以從內(nèi)存中釋放已結束的子進程的 PCB匣距;而如若父進程沒有這么做的話面哥,子進程的 PCB 就會一直駐留在內(nèi)存中,一直留在系統(tǒng)中成為僵尸進程(Zombie)毅待。
雖然僵尸進程是已經(jīng)放棄了幾乎所有內(nèi)存空間幢竹,沒有任何可執(zhí)行代碼,也不能被調(diào)度恩静,在進程列表中保留一個位置焕毫,記載該進程的退出狀態(tài)等信息供其父進程收集,從而釋放它驶乾。但是 Linux 系統(tǒng)中能使用的 PID 是有限的邑飒,如果系統(tǒng)中存在有大量的僵尸進程,系統(tǒng)將會因為沒有可用的 PID 從而導致不能產(chǎn)生新的進程级乐。
另外如果父進程結束(非正常的結束)疙咸,未能及時收回子進程,子進程仍在運行风科,這樣的子進程稱之為孤兒進程撒轮。在 Linux 系統(tǒng)中乞旦,孤兒進程一般會被 init 進程所“收養(yǎng)”,成為 init 的子進程题山。由 init 來做善后處理兰粉,所以它并不至于像僵尸進程那樣無人問津,不管不顧顶瞳,大量存在會有危害玖姑。
進程 0 是系統(tǒng)引導時創(chuàng)建的一個特殊進程,也稱之為內(nèi)核初始化慨菱,其最后一個動作就是調(diào)用 fork() 創(chuàng)建出一個子進程運行 /sbin/init 可執(zhí)行文件焰络,而該進程就是 PID=1 的進程 1,而進程 0 就轉為交換進程(也被稱為空閑進程)符喝,進程 1 (init 進程)是第一個用戶態(tài)的進程闪彼,再由它不斷調(diào)用 fork() 來創(chuàng)建系統(tǒng)里其他的進程,所以它是所有進程的父進程或者祖先進程协饲。同時它是一個守護程序畏腕,直到計算機關機才會停止。
通過以下的命令我們可以很明顯的看到這樣的結構

pstree

或者從此圖我們可以更加形象的看清子父進程的關系


image.png

通過以上的顯示結果我們可以看的很清楚囱稽,init 為所有進程的父進程或者說是祖先進程
我們還可以使用這樣一個命令來看郊尝,其中 pid 就是該進程的一個唯一編號二跋,ppid 就是該進程的父進程的 pid战惊,command 表示的是該進程通過執(zhí)行什么樣的命令或者腳本而產(chǎn)生的

ps -fxo user,ppid,pid,pgid,command
image.png

可以在圖中看見我們執(zhí)行的 ps 就是由 zsh 通過 fork-exec 創(chuàng)建的子進程而執(zhí)行的
使用這樣的一個命令我們也能清楚的看見 init 如上文所說是由進程 0 這個初始化進程來創(chuàng)建出來的子進程,而其他的進程基本是由 init 創(chuàng)建的子進程扎即,或者是由它的子進程創(chuàng)建出來的子進程吞获。所以 init 是用戶進程的第一個進程也是所有用戶進程的父進程或者祖先進程。(ps 命令將在后續(xù)課程詳解)
就像一個樹狀圖谚鄙,而 init 進程就是這棵樹的根各拷,其他進程由根不斷的發(fā)散,開枝散葉

進程組與 Sessions

每一個進程都會是一個進程組的成員闷营,而且這個進程組是唯一存在的烤黍,他們是依靠 PGID(process group ID)來區(qū)別的,而每當一個進程被創(chuàng)建的時候傻盟,它便會成為其父進程所在組中的一員速蕊。
一般情況,進程組的 PGID 等同于進程組的第一個成員的 PID娘赴,并且這樣的進程稱為該進程組的領導者规哲,也就是領導進程,進程一般通過使用 getpgrp() 系統(tǒng)調(diào)用來尋找其所在組的 PGID诽表,領導進程可以先終結唉锌,此時進程組依然存在隅肥,并持有相同的 PGID,直到進程組中最后一個進程終結袄简。
與進程組類似腥放,每當一個進程被創(chuàng)建的時候,它便會成為其父進程所在 Session 中的一員痘番,每一個進程組都會在一個 Session 中捉片,并且這個 Session 是唯一存在的,
Session 主要是針對一個 tty 建立汞舱,Session 中的每個進程都稱為一個工作(job)伍纫。每個會話可以連接一個終端(control terminal)。當控制終端有輸入輸出時昂芜,都傳遞給該會話的前臺進程組莹规。Session 意義在于將多個 jobs 囊括在一個終端,并取其中的一個 job 作為前臺泌神,來直接接收該終端的輸入輸出以及終端信號良漱。 其他 jobs 在后臺運行。

前臺(foreground)就是在終端中運行欢际,能與你有交互的
后臺(background)就是在終端中運行母市,但是你并不能與其任何的交互,也不會顯示其執(zhí)行的過程

工作管理

bash(Bourne-Again shell)支持工作控制(job control)损趋,而 sh(Bourne shell)并不支持患久。
并且每個終端或者說 bash 只能管理當前終端中的 job,不能管理其他終端中的 job浑槽。比如我當前存在兩個 bash 分別為 bash1蒋失、bash2,bash1 只能管理其自己里面的 job 并不能管理 bash2 里面的 job
我們都知道當一個進程在前臺運作時我們可以用 ctrl + c 來終止它桐玻,但是若是在后臺的話就不行了篙挽。
我們可以通過 & 這個符號,讓我們的命令在后臺中運行:

ls &
image.png

圖中所顯示的 [1] 236分別是該 job 的 job number 與該進程的 PID镊靴,而最后一行的 Done 表示該命令已經(jīng)在后臺執(zhí)行完畢铣卡。
我們還可以通過 ctrl + z 使我們的當前工作停止并丟到后臺中去


image.png

被停止并放置在后臺的工作我們可以使用這個命令來查看:

jobs
image.png

其中第一列顯示的為被放置后臺 job 的編號,而第二列的 + 表示最近(剛剛偏竟、最后)被放置后臺的 job煮落,同時也表示預設的工作,也就是若是有什么針對后臺 job 的操作苫耸,首先對預設的 job州邢,- 表示倒數(shù)第二(也就是在預設之前的一個)被放置后臺的工作,倒數(shù)第三個(再之前的)以后都不會有這樣的符號修飾,第三列表示它們的狀態(tài)量淌,而最后一列表示該進程執(zhí)行的命令骗村。
我們可以通過這樣的一個命令將后臺的工作拿到前臺來:

# 后面不加參數(shù)提取預設工作,加參數(shù)提取指定工作的編號
# ubuntu 在 zsh 中需要 %呀枢,在 bash 中不需要 %
fg [%jobnumber]
image.png

image.png

之前我們通過 ctrl + z 使得工作停止放置在后臺胚股,若是我們想讓其在后臺運作我們就使用這樣一個命令:

#與fg類似,加參則指定裙秋,不加參則取預設
bg [%jobnumber]
image.png

既然有方法將被放置在后臺的工作提至前臺或者讓它從停止變成繼續(xù)運行在后臺琅拌,當然也有方法刪除一個工作,或者重啟等等摘刑。

# kill的使用格式如下
kill -signal %jobnumber

# signal從1-64個信號值可以選擇进宝,可以這樣查看
kill -l

其中常用的有這些信號值


image.png

image.png

若是在使用 kill +信號值然后直接加 pid,你將會對 pid 對應的進程進行操作枷恕。
若是在使用 kill+信號值然后 %jobnumber党晋,這時所操作的對象是 job,這個數(shù)字就是就當前 bash 中后臺的運行的 job 的 ID徐块。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末未玻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胡控,更是在濱河造成了極大的恐慌扳剿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昼激,死亡現(xiàn)場離奇詭異庇绽,居然都是意外死亡,警方通過查閱死者的電腦和手機癣猾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門敛劝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余爆,“玉大人纷宇,你說我怎么就攤上這事《攴剑” “怎么了像捶?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桩砰。 經(jīng)常有香客問我拓春,道長,這世上最難降的妖魔是什么亚隅? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任硼莽,我火速辦了婚禮,結果婚禮上煮纵,老公的妹妹穿的比我還像新娘懂鸵。我一直安慰自己偏螺,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布匆光。 她就那樣靜靜地躺著套像,像睡著了一般。 火紅的嫁衣襯著肌膚如雪终息。 梳的紋絲不亂的頭發(fā)上夺巩,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音周崭,去河邊找鬼柳譬。 笑死,一個胖子當著我的面吹牛续镇,可吹牛的內(nèi)容都是我干的征绎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼磨取,長吁一口氣:“原來是場噩夢啊……” “哼人柿!你這毒婦竟也來了?” 一聲冷哼從身側響起忙厌,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凫岖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后逢净,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哥放,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年爹土,在試婚紗的時候發(fā)現(xiàn)自己被綠了甥雕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡胀茵,死狀恐怖社露,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琼娘,我是刑警寧澤峭弟,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脱拼,受9級特大地震影響瞒瘸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熄浓,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一情臭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦俯在、人聲如沸丁侄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸿摇。三九已至,卻和暖如春劈猿,著一層夾襖步出監(jiān)牢的瞬間拙吉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工揪荣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筷黔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓仗颈,卻偏偏與公主長得像佛舱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挨决,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容