久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > Linux下多任務編程之任務、進程和線程詳解,厲害的

Linux下多任務編(bian)程之(zhi)任務、進程和線程詳解,厲(li)害的(de) 時間(jian):2018-06-25  ;    來源:未知

多(duo)(duo)任務是(shi)指用戶(hu)可(ke)以在(zai)同(tong)一時間內運行多(duo)(duo)個應用程(cheng)(cheng)序。Linux就是(shi)一種支持多(duo)(duo)任務的(de)操作(zuo)系統,它(ta)支持多(duo)(duo)進程(cheng)(cheng)、多(duo)(duo)線程(cheng)(cheng)等多(duo)(duo)任務處(chu)理(li)和(he)任務之間的(de)多(duo)(duo)種通信機制(zhi)。掌(zhang)握多(duo)(duo)任務開發,會有助于大家成為系統工(gong)程(cheng)(cheng)師。

Linux下多任務機(ji)制的介紹(shao)

Linux就是一個(ge)(ge)(ge)支(zhi)持多(duo)(duo)(duo)(duo)任(ren)務(wu)(wu)(wu)的(de)操作(zuo)系(xi)統,它比單(dan)任(ren)務(wu)(wu)(wu)系(xi)統的(de)功能增強(qiang)了(le)許多(duo)(duo)(duo)(duo)。當多(duo)(duo)(duo)(duo)任(ren)務(wu)(wu)(wu)操作(zuo)系(xi)統使用某種(zhong)任(ren)務(wu)(wu)(wu)調度策略允(yun)許兩(liang)個(ge)(ge)(ge)或更多(duo)(duo)(duo)(duo)進(jin)程(cheng)(cheng)并(bing)發(fa)共享(xiang)一個(ge)(ge)(ge)處(chu)理(li)器時(shi),事實上處(chu)理(li)器在(zai)某一時(shi)刻只會給一個(ge)(ge)(ge)任(ren)務(wu)(wu)(wu)提供服務(wu)(wu)(wu)。由于任(ren)務(wu)(wu)(wu)調度機制(zhi)保證(zheng)了(le)不同的(de)任(ren)務(wu)(wu)(wu)之間的(de)切(qie)換速度十分(fen)迅速,因(yin)此(ci)給人多(duo)(duo)(duo)(duo)個(ge)(ge)(ge)任(ren)務(wu)(wu)(wu)同時(shi)運(yun)行(xing)的(de)錯覺。多(duo)(duo)(duo)(duo)任(ren)務(wu)(wu)(wu)系(xi)統中有3個(ge)(ge)(ge)功能單(dan)位:任(ren)務(wu)(wu)(wu)、進(jin)程(cheng)(cheng)和線(xian)程(cheng)(cheng),下面分(fen)別進(jin)程(cheng)(cheng)介(jie)紹。

1、任務

任(ren)務(wu)(wu)是一(yi)(yi)(yi)個(ge)(ge)邏(luo)輯概(gai)念,指由(you)一(yi)(yi)(yi)個(ge)(ge)軟件(jian)(jian)完成的(de)(de)活(huo)動,或(huo)(huo)者(zhe)是一(yi)(yi)(yi)系(xi)列共同(tong)達到某一(yi)(yi)(yi)個(ge)(ge)目(mu)的(de)(de)的(de)(de)操作。通常一(yi)(yi)(yi)個(ge)(ge)任(ren)務(wu)(wu)是一(yi)(yi)(yi)個(ge)(ge)程(cheng)(cheng)(cheng)序的(de)(de)一(yi)(yi)(yi)次運行(xing)(xing),一(yi)(yi)(yi)個(ge)(ge)任(ren)務(wu)(wu)包含(han)一(yi)(yi)(yi)個(ge)(ge)或(huo)(huo)多(duo)(duo)個(ge)(ge)完成獨立(li)功(gong)(gong)(gong)能(neng)的(de)(de)子任(ren)務(wu)(wu),這個(ge)(ge)獨立(li)的(de)(de)子任(ren)務(wu)(wu)就(jiu)是進(jin)程(cheng)(cheng)(cheng)或(huo)(huo)線(xian)(xian)程(cheng)(cheng)(cheng)。例(li)如,一(yi)(yi)(yi)個(ge)(ge)殺(sha)(sha)毒軟件(jian)(jian)的(de)(de)一(yi)(yi)(yi)次運行(xing)(xing)是一(yi)(yi)(yi)個(ge)(ge)任(ren)務(wu)(wu),目(mu)的(de)(de)是從各(ge)種病毒的(de)(de)侵害(hai)中保(bao)護計算機系(xi)統(tong),這個(ge)(ge)任(ren)務(wu)(wu)包含(han)多(duo)(duo)個(ge)(ge)獨立(li)功(gong)(gong)(gong)能(neng)的(de)(de)子任(ren)務(wu)(wu)(進(jin)程(cheng)(cheng)(cheng)或(huo)(huo)線(xian)(xian)程(cheng)(cheng)(cheng)),包含(han)實時監控功(gong)(gong)(gong)能(neng)、定時查殺(sha)(sha)功(gong)(gong)(gong)能(neng)、防火墻功(gong)(gong)(gong)能(neng)及用(yong)戶交(jiao)互功(gong)(gong)(gong)能(neng)等。個(ge)(ge)人理(li)解:就(jiu)好比假設(she)一(yi)(yi)(yi)個(ge)(ge)應(ying)(ying)用(yong)程(cheng)(cheng)(cheng)序中由(you)一(yi)(yi)(yi)個(ge)(ge)或(huo)(huo)多(duo)(duo)個(ge)(ge)可(ke)執(zhi)(zhi)行(xing)(xing)文(wen)件(jian)(jian)共同(tong)執(zhi)(zhi)行(xing)(xing)組成,那(nei)么(me)此應(ying)(ying)用(yong)程(cheng)(cheng)(cheng)序的(de)(de)一(yi)(yi)(yi)次執(zhi)(zhi)行(xing)(xing)就(jiu)是一(yi)(yi)(yi)個(ge)(ge)任(ren)務(wu)(wu),而(er)這些可(ke)執(zhi)(zhi)行(xing)(xing)文(wen)件(jian)(jian)的(de)(de)執(zhi)(zhi)行(xing)(xing)就(jiu)是一(yi)(yi)(yi)個(ge)(ge)進(jin)程(cheng)(cheng)(cheng)的(de)(de)執(zhi)(zhi)行(xing)(xing),而(er)可(ke)執(zhi)(zhi)行(xing)(xing)文(wen)件(jian)(jian)是由(you)一(yi)(yi)(yi)個(ge)(ge)線(xian)(xian)程(cheng)(cheng)(cheng)或(huo)(huo)多(duo)(duo)個(ge)(ge)線(xian)(xian)程(cheng)(cheng)(cheng)構成的(de)(de),當只有一(yi)(yi)(yi)個(ge)(ge)線(xian)(xian)程(cheng)(cheng)(cheng)構成了這個(ge)(ge)進(jin)程(cheng)(cheng)(cheng),則此時進(jin)程(cheng)(cheng)(cheng)和線(xian)(xian)程(cheng)(cheng)(cheng)就(jiu)是一(yi)(yi)(yi)樣的(de)(de)概(gai)念(可(ke)執(zhi)(zhi)行(xing)(xing)文(wen)件(jian)(jian)的(de)(de)一(yi)(yi)(yi)次運行(xing)(xing))。

2、進程

進(jin)程的基本概念

進(jin)程是一(yi)個具有獨立功能的(de)(de)程序(xu)在某(mou)個數據集上的(de)(de)一(yi)次動態執(zhi)行(xing)過程,它(ta)是系(xi)統(tong)進(jin)行(xing)資源(yuan)分(fen)(fen)配和調(diao)度(du)的(de)(de)基(ji)本單位(wei)(個人(ren)理解:系(xi)統(tong)好比是一(yi)個大(da)型的(de)(de)任務,由(you)多個進(jin)程(可(ke)執(zhi)行(xing)文件)構成(cheng),而資源(yuan)分(fen)(fen)配和資源(yuan)調(diao)度(du)分(fen)(fen)別都(dou)是一(yi)個進(jin)程,所(suo)以(yi)進(jin)程是系(xi)統(tong)進(jin)行(xing)資源(yuan)分(fen)(fen)配和調(diao)度(du)的(de)(de)基(ji)本單位(wei))。一(yi)次任務的(de)(de)運行(xing)可(ke)以(yi)并發激活多個進(jin)程,這些進(jin)程相互(hu)合作(zuo)來(lai)完成(cheng)該(gai)任務的(de)(de)一(yi)個最終(zhong)的(de)(de)目標。

進程具有并發性(xing)(xing)、動態性(xing)(xing)、交互(hu)性(xing)(xing)、獨立性(xing)(xing)和異步性(xing)(xing)等主要(yao)特(te)性(xing)(xing)

· 并發性:指(zhi)的是系統(tong)中多個(ge)進程可以同時并發執行(xing),相互之間不受(shou)干擾。

· 動態性(xing):指的(de)是進(jin)程(cheng)都有(you)完整的(de)生命周期(qi)(qi),而且在進(jin)程(cheng)的(de)生命周期(qi)(qi)內(nei),進(jin)程(cheng)的(de)狀(zhuang)態是不斷變化的(de)。另外,進(jin)程(cheng)具有(you)動態的(de)地(di)址空間(包括代(dai)碼、數據和進(jin)程(cheng)控制塊)。

· 交互(hu)性:指(zhi)的是進程(cheng)在執行過(guo)程(cheng)中可能會與其他進程(cheng)發(fa)生直接和間接的交互(hu)操(cao)作,如進程(cheng)同步和進程(cheng)互(hu)斥等,需要為此添加一定的進程(cheng)處(chu)理機制。

· 獨立性:指的是(shi)(shi)(shi)進(jin)程是(shi)(shi)(shi)一(yi)個相對完整的資(zi)源分配和調度的基本單(dan)位(wei),各個進(jin)程的地址空間是(shi)(shi)(shi)相互獨立的,只有采用某些特定的通(tong)信(xin)機(ji)制才能實現進(jin)程間的通(tong)信(xin)。

· 異步性:指的(de)是每個進程都按(an)照各自獨立的(de)、不可預知的(de)速度向(xiang)前執(zhi)行。

進程(cheng)(cheng)(cheng)和程(cheng)(cheng)(cheng)序(xu)是有(you)本質的(de)區別:程(cheng)(cheng)(cheng)序(xu)是靜態(tai)的(de)一(yi)段代(dai)碼(ma),是一(yi)些保存在(zai)非(fei)易(yi)失(shi)性存儲器的(de)指(zhi)令的(de)有(you)序(xu)集(ji)合,沒有(you)任何執行(xing)的(de)概念(nian);而(er)進程(cheng)(cheng)(cheng)是一(yi)個動(dong)態(tai)的(de)概念(nian),它是程(cheng)(cheng)(cheng)序(xu)執行(xing)的(de)過程(cheng)(cheng)(cheng),包(bao)括動(dong)態(tai)創建、調度和消(xiao)亡的(de)整個過程(cheng)(cheng)(cheng),它是程(cheng)(cheng)(cheng)序(xu)執行(xing)和資源(yuan)管理的(de)最小單位。

Linux系統中包(bao)括以下幾種(zhong)類型(xing)的過程(cheng):

· 交(jiao)互(hu)式(shi)過程(cheng)(cheng)(cheng)(cheng)(cheng):這類進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)與(yu)用(yong)(yong)戶(hu)進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)交(jiao)互(hu),因此要花很多時(shi)間等待用(yong)(yong)戶(hu)的(de)交(jiao)互(hu)操(cao)作(zuo)(zuo)(鍵盤和鼠標(biao)操(cao)作(zuo)(zuo)等)。當接收(shou)到(dao)用(yong)(yong)戶(hu)的(de)交(jiao)互(hu)操(cao)作(zuo)(zuo)后,這類進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)應該很快(kuai)被允許(xu),而且相應時(shi)間的(de)變化也應該很小(xiao),否則用(yong)(yong)戶(hu)就會覺得系統(tong)反應遲鈍或者不(bu)太穩定。典型(xing)的(de)交(jiao)互(hu)式(shi)進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)有shell命令(ling)進(jin)程(cheng)(cheng)(cheng)(cheng)(cheng)、文本編輯器和圖形(xing)應用(yong)(yong)程(cheng)(cheng)(cheng)(cheng)(cheng)序運行等。

· 批處(chu)理進(jin)(jin)程:這(zhe)類進(jin)(jin)程不必與用(yong)戶(hu)進(jin)(jin)行交互(hu),因(yin)(yin)此(ci)進(jin)(jin)程在后臺運行。因(yin)(yin)為這(zhe)類進(jin)(jin)程通常不必很(hen)快地相(xiang)應(ying),因(yin)(yin)此(ci)往往受到調度(du)器的(de)“慢待”。典型的(de)批處(chu)理進(jin)(jin)程有編(bian)譯(yi)器的(de)編(bian)譯(yi)操作、數(shu)據庫搜索引擎等。

· 實時(shi)(shi)進程(cheng)(cheng)(cheng):這類進程(cheng)(cheng)(cheng)通(tong)常對(dui)調度響(xiang)應時(shi)(shi)間有很(hen)(hen)高的(de)要(yao)求(qiu),一般(ban)不會被低優先級的(de)進程(cheng)(cheng)(cheng)阻塞。它(ta)們不僅要(yao)求(qiu)很(hen)(hen)短的(de)響(xiang)應時(shi)(shi)間,而(er)且更重要(yao)的(de)是(shi)響(xiang)應時(shi)(shi)間的(de)變(bian)化(hua)應該很(hen)(hen)小。典型的(de)實時(shi)(shi)進程(cheng)(cheng)(cheng)有視頻(pin)和音頻(pin)的(de)應用程(cheng)(cheng)(cheng)序(xu)、實時(shi)(shi)數(shu)據采(cai)集系(xi)統程(cheng)(cheng)(cheng)序(xu)等。

Linux下(xia)的進程結構(gou)

進程(cheng)不但(dan)包括程(cheng)序的指令和數據(ju)(ju),而(er)且包括程(cheng)序計(ji)數器(qi)和處理(li)器(qi)的所有寄存器(qi)以及存儲(chu)臨(lin)時數據(ju)(ju)的進程(cheng)堆棧,因(yin)此正在執行的進程(cheng)包括處理(li)器(qi)當前(qian)的一(yi)切活(huo)動。

因(yin)為Linux是一(yi)個(ge)多進程(cheng)的(de)(de)操作系(xi)統,所(suo)以其(qi)他(ta)的(de)(de)進程(cheng)必須(xu)等(deng)到系(xi)統將(jiang)處(chu)(chu)理(li)器(qi)使(shi)用權分(fen)配(pei)各(ge)自(zi)己(ji)之后才能運行。當(dang)正在運行的(de)(de)進程(cheng)等(deng)待其(qi)他(ta)的(de)(de)系(xi)統資源(yuan)時,Linux內核(he)將(jiang)取得處(chu)(chu)理(li)器(qi)的(de)(de)控制權,并(bing)將(jiang)處(chu)(chu)理(li)器(qi)分(fen)配(pei)給其(qi)他(ta)正在等(deng)待的(de)(de)進程(cheng),它按照內核(he)中的(de)(de)調度(du)算法決定處(chu)(chu)理(li)器(qi)分(fen)配(pei)給哪(na)個(ge)進程(cheng)。

內核將所有進程存放在雙向循環鏈表(進程鏈表)中,其中鏈表的頭是init_task描述符。鏈表的每一項都是類型為task_struct,稱為進程描述符的結構,該結構包含了與一個進程相關的所有信息,定義在文件中。task_struct內核結構比較大,它能完整地描述一個進程,如進程的狀態、進程的基本信息、進程標識符、內存相關信息、父進程相關信息、與進程相關的終端信息、當前工作目錄、打開的文件信息、所接收到的信號信息等。

下(xia)面詳細講(jiang)解(jie)task_struct結構中(zhong)最為(wei)重要的兩個(ge)域:state(進程(cheng)狀態)和(he)pid(進程(cheng)標識(shi)符,即(ji)進程(cheng)號)。

1)進程狀態,Linux中的進程有以下幾種狀態

· 運行(xing)狀態(tai)(TASK_RUNNING):進(jin)程當前正在運行(xing),或(huo)者(zhe)正在運行(xing)隊列中等待調度。

創(chuang)建一個task.c文件(jian),task.c文件(jian)內容如下:

多任務編程

保存后,輸入gcc task.c -o task編譯生成二進制代碼task,輸入./task運行(xing)task進程

多任務編程

打開另一個(ge)終端(duan),輸入ps -aux查看進(jin)程狀(zhuang)態:(ps -axjf 可查看進(jin)程有哪些子(zi)進(jin)程,ps -e 也 可以查到進(jin)程的狀(zhuang)態,但只顯示進(jin)程的PID、TTY、TIME和CMD)

ps工具標識進程的(de)5中(zhong)狀態碼:

D 不(bu)可中斷 uninterruptible sleep (usually IO)

R 運行(xing) runnable (on run queue)

S 中斷 sleeping

T 停止 traced or stopped

Z 僵尸(shi) a defunct ("zombie") process

注:其它狀態還包括W(無駐留頁),<(高優先(xian)級進程(cheng)),N(低優先(xian)級進程(cheng)),L(內存鎖頁)

每(mei)列對應關系:

USER:進程所有者

PID:進程(cheng)ID

%CPU:占用CPU的使用率(lv)

%MEM:占用(yong)內存的使用(yong)率

VSZ:占用虛(xu)擬(ni)內存(cun)大小

RSS:占(zhan)用內存大小

TTY:終(zhong)端次要裝置號碼

STAT:進程狀態

START:進(jin)程啟(qi)動時間

TIME:進(jin)程消耗cup時間

COMMAND:命(ming)令的名稱和參數

多任務編程
多任務編程
多任務編程

· 可中(zhong)斷的(de)阻(zu)塞狀態(TASK_INTERRUPTIBLE):進程(cheng)處于(yu)阻(zu)塞(睡眠)狀態,正在等待某些(xie)事(shi)件發生(sheng)或能夠(gou)占(zhan)用某些(xie)資源。處在這種狀態下的(de)進程(cheng)可以(yi)被(bei)信號中(zhong)斷。接收(shou)到信號或被(bei)顯(xian)式的(de)喚醒呼叫(如(ru)調(diao)用wake_up系列宏:wake_up、wake_up_interruptible等)喚醒之后,進程(cheng)轉(zhuan)變為(wei)TASK_RUNNING狀態。

· 不(bu)可中(zhong)斷(duan)的(de)阻塞狀態(tai)(TASK_UNINTERRUPTIBLE):此進程狀態(tai)類似于可中(zhong)斷(duan)的(de)阻塞狀態(tai)(TASK_INTERRUPTILBE),只(zhi)是(shi)它(ta)不(bu)會處理信(xin)號,把信(xin)號傳遞到這(zhe)種(zhong)狀態(tai)下的(de)進程不(bu)能改(gai)變它(ta)的(de)狀態(tai)。在(zai)一(yi)些特定的(de)情況下(進程必須等待,直到某些不(bu)可被中(zhong)斷(duan)的(de)事件(jian)發生(sheng)),這(zhe)種(zhong)狀態(tai)是(shi)很有用的(de)。只(zhi)有在(zai)它(ta)所等待的(de)事件(jian)發生(sheng)時(shi),進程被顯式的(de)喚(huan)(huan)醒(xing)呼叫(jiao)喚(huan)(huan)醒(xing)。

· 可終止的(de)(de)(de)阻塞(sai)狀態(tai)(tai)(TASK_KILLABLE):Linux內(nei)核2.6.25引(yin)入了(le)一種(zhong)新的(de)(de)(de)進程狀態(tai)(tai),名為TASK_KILLABLE。該(gai)狀態(tai)(tai)的(de)(de)(de)運行(xing)機制類(lei)似于(yu)TASK_UNINTERRUPTILBE,只不(bu)過在該(gai)狀態(tai)(tai)下(xia)的(de)(de)(de)進程可以響(xiang)應致(zhi)命信號。它可以替(ti)代有效但(dan)可能無法終止的(de)(de)(de)不(bu)可中(zhong)斷的(de)(de)(de)阻塞(sai)狀態(tai)(tai),以及易于(yu)喚醒安全(quan)性欠佳的(de)(de)(de)可中(zhong)斷的(de)(de)(de)阻塞(sai)狀態(tai)(tai)。

· 暫停(ting)狀態(TASK_STOPPED):進(jin)程的執行被暫停(ting),當進(jin)程收(shou)到SIGTOP、SIGTSTP、SIGTTIN、SIGTTOU等信號(hao)時,就會進(jin)入暫停(ting)狀態。

· 跟(gen)(gen)蹤狀態(tai)(tai)(TASK_TRACED):進(jin)程的執行(xing)被(bei)調試器暫停。當(dang)一(yi)個(ge)進(jin)程被(bei)另(ling)一(yi)個(ge)進(jin)程監控是(如調試器使用(yong)ptrace()系統調用(yong)監控測試程序),任何信號都(dou)可以把這個(ge)進(jin)程置(zhi)于跟(gen)(gen)蹤狀態(tai)(tai)。

· 僵尸(shi)狀(zhuang)(zhuang)態(EXIT_ZOMBIE):進(jin)(jin)(jin)程(cheng)運(yun)行結束(shu),父(fu)進(jin)(jin)(jin)程(cheng)尚未使用(yong)wait函數族(如使用(yong)waitpid()函數)等系統調(diao)用(yong)來“收尸(shi)”,即等待父(fu)進(jin)(jin)(jin)程(cheng)銷毀它(ta)。處(chu)于(yu)該(gai)狀(zhuang)(zhuang)態下的(de)進(jin)(jin)(jin)程(cheng)“實體(ti)”已經放(fang)棄了幾乎所有(you)的(de)內存空間,沒有(you)任何可(ke)執行代碼,也不(bu)能調(diao)度,僅僅在進(jin)(jin)(jin)程(cheng)列表(biao)保留一個位置,記載該(gai)進(jin)(jin)(jin)程(cheng)的(de)退出狀(zhuang)(zhuang)態等信息供其他進(jin)(jin)(jin)程(cheng)收集。

· 僵(jiang)尸撤銷狀(zhuang)態(tai)(EXIT_DEAD):這(zhe)是最終狀(zhuang)態(tai),父進程(cheng)調用wait函數族&ldquo;收尸”后,進程(cheng)徹底有系(xi)統刪除。

它(ta)們之間的轉換(huan)關系如圖所示(shi):

內核可以使用(yong)set_task_state和(he)set_current_state宏來改(gai)變指(zhi)定進(jin)程(cheng)(cheng)的狀態和(he)當前(qian)執行(xing)進(jin)程(cheng)(cheng)的狀態。

2)進程(cheng)標(biao)識符

Linux內核(he)通(tong)過唯一(yi)的(de)進程標(biao)識符(fu)PID來(lai)標(biao)識每(mei)個進程。PID存放進程描述符(fu)的(de)pid字段(duan)中(zhong),新創建的(de)PID通(tong)常是前一(yi)個進程的(de)PID加(jia)1,不(bu)過PID的(de)值(zhi)有(you)上(shang)限(最大值(zhi) = PID_MAX_DEFAULT - 1,通(tong)常為32767),我們可以在終端輸(shu)入 vim /proc/sys/kernel/pid_max 來(lai)確定該系統的(de)進程數上(shang)限。

當(dang)系統(tong)啟動(dong)后,內核通常作(zuo)為一個進程(cheng)的(de)代表(biao)。一個指(zhi)向task_struct的(de)宏current用(yong)來記(ji)錄正(zheng)(zheng)在運行的(de)進程(cheng)。current經(jing)常作(zuo)為進程(cheng)描述符結構指(zhi)針的(de)形式出現在內核代碼中,例如,current->pid表(biao)示處(chu)理器正(zheng)(zheng)在執行進程(cheng)的(de)PID。當(dang)系統(tong)需(xu)要查看(kan)所(suo)有的(de)進程(cheng)時,則(ze)調用(yong)for_each_process()宏,這將(jiang)比系統(tong)搜索數組的(de)速度(du)要快得多。

在Linux中獲得當前(qian)進(jin)程的進(jin)程號(PID)和(he)(he)父進(jin)程號(PPID)的系(xi)統調(diao)用函數分別為(wei)getpid()和(he)(he)getppid()。

測試代碼:

測試結果:

輸入 ps -axjf 命令查(cha)看所有進程(cheng)(cheng)與父進程(cheng)(cheng)

我們在(zai)次輸入ps -aux命令查看所有進(jin)程(cheng)(cheng),可以得(de)知父進(jin)程(cheng)(cheng)為bash

進程(cheng)的(de)創建、執行和終止

1)進程的創建和執行(xing)

許多操(cao)作系(xi)統(tong)提供的(de)(de)都(dou)是(shi)產生進程的(de)(de)機(ji)制(zhi),也就是(shi)說,首先(xian)在(zai)新的(de)(de)地址空(kong)(kong)間里創建(jian)進程、讀(du)入(ru)可(ke)執(zhi)(zhi)行(xing)文(wen)件(jian)(jian)、最后在(zai)開始執(zhi)(zhi)行(xing)。Linux中進程的(de)(de)穿(chuan)件(jian)(jian)很特別,它把(ba)上述步驟分解到兩(liang)個單獨的(de)(de)函數(shu)中去執(zhi)(zhi)行(xing):fork()和exec函數(shu)族。首先(xian)fork()函數(shu)通過復制(zhi)當前進程創建(jian)一(yi)個子進程,子進程與(yu)父進程的(de)(de)區別在(zai)于(yu)不同(tong)的(de)(de)PID、PPID和某些資(zi)源及統(tong)計量。exec函數(shu)族負責讀(du)取可(ke)執(zhi)(zhi)行(xing)文(wen)件(jian)(jian)并將(jiang)其載入(ru)地址空(kong)(kong)間開始運行(xing)。

要(yao)注(zhu)意的(de)是,Linux中的(de)fork()函數(shu)(shu)使用(yong)的(de)是寫時(shi)復(fu)(fu)制頁的(de)技(ji)術(shu),也就是內核(he)在創建(jian)進程時(shi),其資(zi)源并沒有(you)被復(fu)(fu)制過來(lai),資(zi)源的(de)復(fu)(fu)制僅僅只(zhi)有(you)在需要(yao)寫入數(shu)(shu)據時(shi)才(cai)發生,在此(ci)之(zhi)前(qian)只(zhi)是以只(zhi)讀的(de)方式共(gong)享數(shu)(shu)據。寫時(shi)復(fu)(fu)制技(ji)術(shu)可以使Linux擁(yong)有(you)快速執行的(de)能(neng)力,因此(ci)這個優(you)化是非常(chang)重要(yao)的(de)。

2)進程的終止

進(jin)(jin)程終(zhong)結(jie)也需要做很多(duo)繁瑣的(de)(de)收(shou)尾(wei)工(gong)作,系統必須保證回收(shou)進(jin)(jin)程所占的(de)(de)資源,并(bing)通(tong)知父進(jin)(jin)程。Linux首(shou)先把終(zhong)止的(de)(de)進(jin)(jin)程設置為僵尸狀(zhuang)態,這(zhe)時,進(jin)(jin)程無法(fa)投(tou)入運行,它的(de)(de)存在只為父進(jin)(jin)程提供信息,申請死亡。父進(jin)(jin)程得到信息后(hou),開始調用(yong)wait函數(shu)族,最后(hou)終(zhong)止子(zi)進(jin)(jin)程,子(zi)進(jin)(jin)程占用(yong)的(de)(de)所有資源被全部釋放。

進(jin)程的內存結(jie)構(gou)

Linux操作系統(tong)采用虛擬內存(cun)管理技術,使得(de)每個進程(cheng)都(dou)有各(ge)自互不(bu)干涉(she)的(de)(de)(de)進程(cheng)地(di)址(zhi)(zhi)空間(jian)。該地(di)址(zhi)(zhi)空間(jian)是大小為(wei)4GB的(de)(de)(de)線性虛擬空間(jian)(當然是指(zhi)32位系統(tong)),用戶(hu)(hu)所看(kan)到(dao)和接(jie)觸到(dao)的(de)(de)(de)都(dou)是該虛擬地(di)址(zhi)(zhi),無法看(kan)到(dao)實(shi)際的(de)(de)(de)物理內存(cun)地(di)址(zhi)(zhi)。利用這種虛擬地(di)址(zhi)(zhi)不(bu)但(dan)能(neng)起到(dao)保護(hu)操作系統(tong)的(de)(de)(de)效果(用戶(hu)(hu)不(bu)能(neng)直接(jie)訪問物理內存(cun)),而且更重要的(de)(de)(de)是,用戶(hu)(hu)程(cheng)序可(ke)以(yi)使用比實(shi)際物理內存(cun)更大的(de)(de)(de)地(di)址(zhi)(zhi)空間(jian)。

我(wo)們(men)可以通(tong)過(guo)命令getconf LONG_BIT 來查詢當前自(zi)己的系(xi)統是(shi)多少位(wei)的?

我的安(an)裝的UbuntKylin是(shi)64位的,即(ji)實際內存最大(da)可能達到2^64 = 128GB。(2^10 = 1kb,2^30 = 1GB)。

4GB的(de)進(jin)(jin)程(cheng)(cheng)地(di)(di)址空(kong)(kong)(kong)間(jian)(jian)會(hui)被分(fen)出兩部分(fen):用(yong)(yong)戶(hu)(hu)空(kong)(kong)(kong)間(jian)(jian)與內(nei)(nei)核(he)空(kong)(kong)(kong)間(jian)(jian)。用(yong)(yong)戶(hu)(hu)地(di)(di)址空(kong)(kong)(kong)間(jian)(jian)是從0~3GB(0xC0000000),內(nei)(nei)存(cun)地(di)(di)址空(kong)(kong)(kong)間(jian)(jian)占據(ju)3GB~4GB。用(yong)(yong)戶(hu)(hu)進(jin)(jin)程(cheng)(cheng)通常情(qing)況下只(zhi)能(neng)訪(fang)問(wen)用(yong)(yong)戶(hu)(hu)控件的(de)虛擬(ni)地(di)(di)址,不(bu)(bu)(bu)能(neng)訪(fang)問(wen)內(nei)(nei)核(he)空(kong)(kong)(kong)間(jian)(jian)的(de)虛擬(ni)地(di)(di)址。只(zhi)有用(yong)(yong)戶(hu)(hu)進(jin)(jin)程(cheng)(cheng)使用(yong)(yong)系統調用(yong)(yong)(代(dai)表(biao)用(yong)(yong)戶(hu)(hu)進(jin)(jin)程(cheng)(cheng)在內(nei)(nei)核(he)執行(xing))時(shi)可以訪(fang)問(wen)內(nei)(nei)核(he)空(kong)(kong)(kong)間(jian)(jian)的(de)虛擬(ni)空(kong)(kong)(kong)間(jian)(jian)。每當進(jin)(jin)程(cheng)(cheng)切換(huan)時(shi),用(yong)(yong)戶(hu)(hu)空(kong)(kong)(kong)間(jian)(jian)就(jiu)會(hui)跟著變(bian)化;而內(nei)(nei)核(he)空(kong)(kong)(kong)間(jian)(jian)有內(nei)(nei)核(he)負(fu)責映射(she),它并不(bu)(bu)(bu)會(hui)跟著進(jin)(jin)程(cheng)(cheng)改(gai)變(bian)而改(gai)變(bian),是固定的(de)。內(nei)(nei)核(he)空(kong)(kong)(kong)間(jian)(jian)地(di)(di)址有自(zi)己(ji)對應的(de)頁(ye)(ye)表(biao),用(yong)(yong)戶(hu)(hu)進(jin)(jin)程(cheng)(cheng)各自(zi)用(yong)(yong)不(bu)(bu)(bu)同的(de)頁(ye)(ye)表(biao)。每個進(jin)(jin)程(cheng)(cheng)用(yong)(yong)戶(hu)(hu)空(kong)(kong)(kong)間(jian)(jian)都是完(wan)全獨立、互不(bu)(bu)(bu)相干的(de)。進(jin)(jin)程(cheng)(cheng)的(de)虛擬(ni)內(nei)(nei)存(cun)地(di)(di)址空(kong)(kong)(kong)間(jian)(jian)如圖所示:

其中用戶空間(jian)包括以(yi)下幾(ji)個功能區域(yu):

· 只讀(du)段:包含程序代碼(.init和(he).exit)和(he)只讀(du)數據(.rodata)

· 數(shu)據(ju)段(duan):存(cun)放(fang)的(de)是全局變(bian)量(liang)(liang)和靜態變(bian)量(liang)(liang)。其中可讀可寫數(shu)據(ju)段(duan)(.data)存(cun)放(fang)已經初始(shi)(shi)化的(de)全局變(bian)量(liang)(liang)和靜態變(bian)量(liang)(liang),BSS數(shu)據(ju)段(duan)(.bss)存(cun)放(fang)未初始(shi)(shi)化的(de)全局變(bian)量(liang)(liang)和靜態變(bian)量(liang)(liang)

· 堆:由(you)系統自(zi)動分配釋放,存放函數的(de)參數值(zhi)、局部變(bian)量的(de)值(zhi)、返回地址等

· 堆(dui)棧:存(cun)放(fang)動態分配的數(shu)據,一般由程序(xu)員(yuan)動態分配和釋(shi)放(fang)。若(ruo)程序(xu)員(yuan)不(bu)釋(shi)放(fang),程序(xu)結束(shu)時(shi)可能由操作系統回收(shou)。

· 共享(xiang)庫(ku)的(de)內存映射區域:這是Linux動態連接器(qi)和其他共享(xiang)庫(ku)代(dai)碼(ma)的(de)映射區域。

由(you)于在Linux系統(tong)中每一個進(jin)程(cheng)都會(hui)有/proc文件(jian)系統(tong)下與之(zhi)對(dui)應的(de)一個目錄(如將init進(jin)程(cheng)的(de)相關信(xin)息在/proc/1 目錄下的(de)文件(jian)中描述(shu),1表(biao)示init進(jin)程(cheng)的(de)進(jin)程(cheng)號),因此通過proc文件(jian)系統(tong)可以(yi)查看某個進(jin)程(cheng)的(de)地址(zhi)空間的(de)映射情況。

測試代碼:

運行此程序:

輸入 size task

text:存放(fang)的是(shi)代碼 data:存放(fang)的是(shi)初始化(hua)過的全(quan)局變(bian)量或靜態變(bian)量 bss:存放(fang)的是(shi)未初始化(hua)的全(quan)局變(bian)量或靜態變(bian)量

輸入(ru)命令 cat /proc/3834/maps 其(qi)中3834是task的PID

3、線程

前面已經提到,進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)是(shi)系統中程(cheng)(cheng)(cheng)(cheng)序執行和資源(yuan)分配的基本單位。每個進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)都擁有自己的數據段(duan)、代(dai)碼段(duan)和堆棧(zhan)段(duan),這(zhe)就(jiu)造(zao)成了進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)切(qie)換等操作(zuo)時需要較(jiao)復雜(za)的上(shang)下文(wen)切(qie)換等動作(zuo)。為了進(jin)(jin)(jin)一(yi)步減少(shao)處(chu)理(li)機制的空轉時間(jian),支持多處(chu)理(li)器及(ji)減少(shao)上(shang)下文(wen)切(qie)換開銷,進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)在演化中出現了另一(yi)個概念——線(xian)程(cheng)(cheng)(cheng)(cheng)。它(ta)是(shi)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)內獨立的一(yi)條(tiao)運(yun)行路線(xian),是(shi)處(chu)理(li)器調用的最小(xiao)單元,也(ye)可以(yi)成為輕量級進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)。線(xian)程(cheng)(cheng)(cheng)(cheng)可以(yi)對(dui)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)的內存空間(jian)和資源(yuan)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)訪問(wen),并與同一(yi)個進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)中的其他線(xian)程(cheng)(cheng)(cheng)(cheng)共享。因此,線(xian)程(cheng)(cheng)(cheng)(cheng)上(shang)下文(wen)切(qie)換的開銷比創建進(jin)(jin)(jin)程(cheng)(cheng)(cheng)(cheng)小(xiao)得(de)多。

 一個進(jin)(jin)程(cheng)(cheng)(cheng)可(ke)以擁(yong)有多(duo)個線(xian)(xian)程(cheng)(cheng)(cheng),每個線(xian)(xian)程(cheng)(cheng)(cheng)必須有一個父(fu)進(jin)(jin)程(cheng)(cheng)(cheng)。線(xian)(xian)程(cheng)(cheng)(cheng)不擁(yong)有系(xi)統資源(yuan),它只具有運行(xing)所必需的(de)一些數據(ju),如堆棧、寄存器(qi)與線(xian)(xian)程(cheng)(cheng)(cheng)控(kong)制塊(TCB),線(xian)(xian)程(cheng)(cheng)(cheng)與其父(fu)進(jin)(jin)程(cheng)(cheng)(cheng)的(de)其他線(xian)(xian)程(cheng)(cheng)(cheng)共享(xiang)該進(jin)(jin)程(cheng)(cheng)(cheng)所擁(yong)有的(de)全部(bu)資源(yuan)。要注意的(de)是,由線(xian)(xian)程(cheng)(cheng)(cheng)共享(xiang)了進(jin)(jin)程(cheng)(cheng)(cheng)的(de)資源(yuan)和地址空間,因此,任(ren)何線(xian)(xian)程(cheng)(cheng)(cheng)對系(xi)統資源(yuan)的(de)操(cao)作都會(hui)給其他線(xian)(xian)程(cheng)(cheng)(cheng)帶來(lai)影響(xiang)。由此可(ke)知,多(duo)線(xian)(xian)程(cheng)(cheng)(cheng)中(zhong)的(de)同步是非常重(zhong)要的(de)問(wen)題。在多(duo)線(xian)(xian)程(cheng)(cheng)(cheng)系(xi)統中(zhong),進(jin)(jin)程(cheng)(cheng)(cheng)與線(xian)(xian)程(cheng)(cheng)(cheng)的(de)關系(xi)如圖所示:

在(zai)Linux系統中,線程可以分為以下3種:

用戶級線程

用(yong)戶(hu)(hu)級線(xian)(xian)程(cheng)(cheng)(cheng)主(zhu)要解(jie)決的是上下文切換的問題,它(ta)的調(diao)度(du)算法(fa)和(he)調(diao)度(du)過程(cheng)(cheng)(cheng)全部由用(yong)戶(hu)(hu)自己(ji)選擇決定(ding),在(zai)運(yun)行時不需要特(te)定(ding)的內(nei)核支持。在(zai)這里,操作系統(tong)往(wang)往(wang)會提供一(yi)(yi)個(ge)(ge)用(yong)戶(hu)(hu)空(kong)間的線(xian)(xian)程(cheng)(cheng)(cheng)庫,該線(xian)(xian)程(cheng)(cheng)(cheng)庫提供了(le)(le)線(xian)(xian)程(cheng)(cheng)(cheng)的創建、調(diao)度(du)和(he)撤(che)銷等(deng)功能,而內(nei)核仍然僅對進(jin)(jin)(jin)程(cheng)(cheng)(cheng)進(jin)(jin)(jin)行管理。如果一(yi)(yi)個(ge)(ge)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)中的某一(yi)(yi)個(ge)(ge)線(xian)(xian)程(cheng)(cheng)(cheng)調(diao)用(yong)了(le)(le)一(yi)(yi)個(ge)(ge)阻塞的系統(tong)調(diao)用(yong)函數,那么該進(jin)(jin)(jin)程(cheng)(cheng)(cheng)好(hao)吧(ba)該進(jin)(jin)(jin)程(cheng)(cheng)(cheng)中的其他所有線(xian)(xian)程(cheng)(cheng)(cheng)也同時被阻塞。這種用(yong)戶(hu)(hu)級線(xian)(xian)程(cheng)(cheng)(cheng)的主(zhu)要缺(que)點是在(zai)一(yi)(yi)個(ge)(ge)進(jin)(jin)(jin)程(cheng)(cheng)(cheng)的多個(ge)(ge)線(xian)(xian)程(cheng)(cheng)(cheng)的調(diao)度(du)中無(wu)法(fa)發揮多處理器(qi)的優勢。

輕量級進程

輕量(liang)(liang)級(ji)進程(cheng)是(shi)內核支持(chi)的用戶線(xian)(xian)程(cheng),是(shi)內核線(xian)(xian)程(cheng)的一(yi)種抽象對象。每個(ge)線(xian)(xian)程(cheng)擁有一(yi)個(ge)或多個(ge)輕量(liang)(liang)級(ji)進程(cheng),而每個(ge)輕量(liang)(liang)級(ji)進程(cheng)分別被綁(bang)定在一(yi)個(ge)內核線(xian)(xian)程(cheng)上。

內核線程

內核線程(cheng)(cheng)(cheng)允(yun)許不(bu)同(tong)進(jin)程(cheng)(cheng)(cheng)中的線程(cheng)(cheng)(cheng)按照(zhao)同(tong)一相對優(you)先(xian)調度(du)方法進(jin)行調度(du),這樣就(jiu)可(ke)(ke)(ke)以(yi)發揮多(duo)(duo)(duo)(duo)處理器的并(bing)發優(you)勢。現(xian)在(zai)大多(duo)(duo)(duo)(duo)數系統都采用(yong)用(yong)戶級線程(cheng)(cheng)(cheng)與(yu)核心級線程(cheng)(cheng)(cheng)并(bing)存的方法。一個(ge)用(yong)戶級線程(cheng)(cheng)(cheng)可(ke)(ke)(ke)以(yi)對應一個(ge)或(huo)(huo)幾個(ge)核心級線程(cheng)(cheng)(cheng),也就(jiu)是(shi)“一對一”或(huo)(huo)“多(duo)(duo)(duo)(duo)對一”模(mo)型(xing)。這樣既(ji)可(ke)(ke)(ke)以(yi)滿足(zu)多(duo)(duo)(duo)(duo)處理系統的需要(yao),也可(ke)(ke)(ke)以(yi)最大限度(du)地減少調度(du)開(kai)銷。

使用線(xian)程(cheng)機制大大加(jia)快(kuai)了上下文(wen)切(qie)換速(su)度,而節省了很多資源。但(dan)是因(yin)為(wei)在用戶態和內核(he)態均要實(shi)現(xian)調度管理(li),所有會增(zeng)加(jia)實(shi)現(xian)的(de)復雜度和引起優(you)先級翻轉的(de)可能性(xing)。同時,一個多線(xian)程(cheng)程(cheng)序(xu)的(de)同步設計與(yu)調試也會增(zeng)加(jia)程(cheng)序(xu)實(shi)現(xian)的(de)難(nan)道。

上一篇:android ui 組件最常用的都在這里,經典中的經典

下一篇:進程標識符詳解,讓你對進程標識符有深入理解

熱點文章推薦(jian)
華清學員(yuan)就業榜單
高薪學員經(jing)驗分享
熱點(dian)新聞(wen)推薦
前臺專線(xian):010-82525158 企業(ye)培訓洽談專線:010-82525379 院校合作洽(qia)談專(zhuan)線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部