行程概念介紹
每次寫筆記的時候總有一種想法,擔心這個觀點是錯誤的.擔心我學到的內容是問題了,從而給看筆記的同學們傳遞一種錯誤的知識.希望看筆記的同學帶疑惑的去看去思考,我寫的是不是有問題,發現錯誤了希望您也能反饋給我.我也從中學到得到.
什么是行程
了解行程之前,需要先了解一下什么是程式,程式就是一個存放在磁盤的有序指令集合,是靜態的;而行程可以簡單理解成磁盤中程式的一個副本,只不過這個副本時動態的,運行臺記憶體空間中.而且一個行程不單單只運行你指定的運行程式的代碼或部分代碼,還包括了程式運行時需要的各種庫檔案和資料資訊.
同時還要一個概念那就是執行緒,執行緒是計算機CPU調度的最小單位,一個行程中可能包含一個執行緒,也可能包含多個執行緒.執行緒就好比公司的員工,而行程就相當于一個公司,一個小公司可能老板和員工是同一個人,同樣的小行程中就只有一個執行緒,有的公司還有很多員工,同樣行程也可能有很多執行緒同時作業.

行程的組成結構
行程是在行程佇列task list中調度行程的,行程佇列又是由一個一個的行程結構體task_sturck組成的雙向回圈結構.可以說一個行程結構體就管理著一個行程,所以這種行程結構體又稱為行程控制塊
一個行程結構體中包含:
行程的ID 用戶ID 和組ID
程式計數器
行程的狀態:就緒態 執行態 睡眠態 阻塞態
行程切換時需要保存和恢復的CPU暫存器中的值
描述虛擬記憶體分配的地址資訊
描述控制終端的資訊
當前作業目錄
檔案描述符表,包含很多指向file結構體的指標
行程可以使用的資源上線
輸入輸出狀態:配置行程使用IO設備
行程眼里的天地:虛擬記憶體空間
行程是運行在虛擬記憶體空間的,在行程眼里虛擬記憶體就只有自己和內核.自己完全享有內核和CPU等硬體資源.
如下圖是以32為系統為例,行程以為自己完全享有0-3G的虛擬記憶體,3G-4G記憶體是內核占有的.行程可供自己完全支配的這部分空間稱為用戶空間,內核占有的那部分空間稱為內核空間.
用戶空間劃分為五個段:
代碼段:Text Segment,這里存放了行程執行時需要用到的代碼.所以這部分是只讀的.
資料段:Data Segment,這里用來存放已經初始化且值不為0的全部變數和靜態區域變數
BSS段::Block Started by Symbol,存放了未初始化或者已經初始化但是值為0的全域變數和靜態區域變數
堆:heap,用于存放陣列和物件,堆是用來存放行程運行中被動態分配的記憶體段,它的大小不固定,可動態擴展或酸堿,單行程呼叫malloc等函式分配記憶體時,新分配的記憶體就被動態添加進堆中,當利用free函式釋放記憶體時,就是從堆中剔除該記憶體.同時因為在不斷的malloc 和free這部分記憶體空間是不連接的,所以堆是用鏈表結構來儲存資料的.
堆疊:stack,堆疊是用來存放新創建的區域變數和函式引數,引數回傳值.由于堆疊的后進先出特性,堆疊特別方便用來保存恢復呼叫現場,即某個行程運行中產生在CPU暫存器中的資料.
內核空間:
內核空間是屬于作業系統的一部分常駐記憶體,作業系統不允許普通用戶的應用程式讀寫這個區域的內容或者直接呼叫內核空間中定義的函式.

虛擬記憶體和物理記憶體的關系:
存放行程的虛擬記憶體最侄訓映射到物理記憶體當中.物理記憶體是怎么分配的呢?
作業系統會把物理記憶體劃分成一個一個的頁框,頁框的大小一般是4k,可以使用
Getconf -a | grep -i size 來搜索查看page 的大小.
[root@CentOS7 411]# getconf -a | grep -i size PAGESIZE 4096 PAGE_SIZE 4096 SSIZE_MAX 32767
在行程看來虛擬記憶體是連續的,而物理記憶體分配的記憶體頁不一定是連續的,就會出現一種出現一種奇怪的映射關系,虛擬記憶體可能對應這多個不連續記憶體頁

可以使用pmap命令來查看某個程式的具體物理地址映射表.也可以通過查看/proc/目錄下對應PID目錄中的maps檔案
[root@CentOS7 proc]# pmap 863 863: /usr/sbin/sshd -D 000055ceab69c000 800K r-x-- sshd 000055ceab963000 16K r---- sshd 000055ceab967000 4K rw--- sshd 000055ceab968000 36K rw--- [ anon ] 000055ceac9a4000 132K rw--- [ anon ] 00007f9732117000 48K r-x-- libnss_files-2.17.so 00007f9732123000 2044K ----- libnss_files-2.17.so
[root@CentOS7 proc]# cat /proc/863/maps 55ceab69c000-55ceab764000 r-xp 00000000 08:03 464614 /usr/sbin/sshd 55ceab963000-55ceab967000 r--p 000c7000 08:03 464614 /usr/sbin/sshd 55ceab967000-55ceab968000 rw-p 000cb000 08:03 464614 /usr/sbin/sshd 55ceab968000-55ceab971000 rw-p 00000000 00:00 0 55ceac9a4000-55ceac9c5000 rw-p 00000000 00:00 0 [heap] 7f9732117000-7f9732123000 r-xp 00000000 08:03 46532 /usr/lib64/libnss_files-2.17.so 7f9732123000-7f9732322000 ---p 0000c000 08:03 46532 /usr/lib64/libnss_files-2.17.so 7f9732322000-7f9732323000 r--p 0000b000 08:03 46532 /usr/lib64/libnss_files-2.17.so 7f9732323000-7f9732324000 rw-p 0000c000 08:03 46532 /usr/lib64/libnss_files-2.17.so
虛擬記憶體是通過CPU中的MMU(Memory Mnagement Unit)完成虛擬記憶體地址和物理記憶體地址之間的轉換.程式在訪問虛擬記憶體地址時,這個虛擬記憶體地址就會先發送給MMU,MMU計算出來實際的物理地址,然后再通過總線去訪問實際的物理地址.
行程狀態
行程的基本狀態:
創建態:行程在創建時需要申請一個空白的行程控制塊PCB,向其中填寫空間和管理行程的資訊,完成資源分配.如果創建作業無法完成.例如資源不足無法分配,卡這一步的狀態就是創建態.
就緒態:行程已經準備好,就差等待CPU分配時間片的狀態
在行程創建完成且已經分配好所需資源后,就會等待分配CPU的時間片的狀態,
在上一個時間片內沒有完成就被保存現場以后等待再次被CPU呼叫的的狀態,
行程在運行時產生長時間的IO操作后經過等待完成IO操作等待被分配時間片時的狀態
執行態:程式正在執行的狀態.擁有CPU的使用權
阻塞態:正在執行的行程由于某些原因產生IO請求而暫時無法運行時,行程就收到阻塞的狀態.這中狀態在滿足請求后就會進入就緒態.
終止態:行程結束或出現錯誤,或者被系統終止的狀態

行程切換路徑6種:
創建 to 就緒
就緒 to 執行
執行 to 就緒
執行 to 阻塞
阻塞 to 就緒
執行 to 結束
行程更多的狀態介紹:
運行態:running
就緒態:reading
睡眠態:分為可中斷睡眠(interruptable)和不可中斷睡眠(uninterruptable)
停止態:stiopped,暫停于記憶體,但不會被再次被調度運行,只能手工啟動
僵尸態:zombie,結束了子行程,但是父行程沒有收尸,此時子行程的狀態就是僵尸態
行程間通訊IPC
Inter process communication
同一主機:
管道
套接字
共享記憶體
信號
檔案映射,將一個檔案中的一段資料映射到物理記憶體中.
鎖
信號量
不同主機:
SOCKET
RPC,remote procedure call
MQ 訊息佇列
行程的優先級
系統優先級:
LIUNX內核將系統優先級劃分兩部分:實時優先級和非實時優先級
實時優先級,0~99
非實時優先級,100~139
實時優先級是給內核使用的,
非實時優先級是給普通行程使用的
優先級中數字越小數字優先級越高
NICE優先級:
NICE優先級知識給普通行程使用的
范圍是-20~19
NICE的-20對應的系統優先級是100
NICE的0對應的系統高優先級是120
NICE的19對應的系統優先級是139
TOP命令中優先級
范圍是0~39
TOP中的0對應系統的優先級是100
TOP中的39對應的系統優先級是139
普通用戶只能調大優先級的數字,意思就是普通用戶不能提高行程的優先級
只有管理員才可以提高行程的優先級.
提到優先級就不得不提下時間復雜度了,這里參考的上頭條作者的文章,我把鏈接放下來:https://www.toutiao.com/a6643648147614597639/,相信感謝作者
時間復雜度O(1)理解:
O(1)表示,隨著計算量的增加他的時間復雜度恒定為固定值.
在linux當中一共有兩組佇列,一組是運行佇列,一組是就緒佇列.每一組佇列當中又由140個子佇列,每個子佇列就代表著一個優先級,表示0~139個優先級.根據行程的優先級就會分布在這140個子佇列中.
系統會首先判斷140個佇列的優先級,把0號佇列的優先級上的行程從前到后先取出一個開始運行,當運行完這個行程后,就會把該行程放進就緒佇列當中,然后再從運行佇列中去下一個行程,運行完在放入到就緒佇列.當0號運行佇列中已經沒有了就緒態的行程就會把,就緒佇列變成運行佇列.而空的原運行佇列就變成就緒佇列.如此往復,實作了系統檢索優先級的時候只是在這280個對聯中查找.所以時間復雜度是恒定的.
時間復雜度O(n)理解:
這里用使用contains()方法使用查找List集合里面的某個元素來舉例,List是有序表,不能直接一次性查找到,比如從{12,23,45,··· ···,76,32}里面查找76,要從12開始查找,一次次回圈查找,直到查到76并回傳,這里每次的查找時間復雜度為O(1),需要查找N次才能查到76,則時間復雜度可以看作是N * O(1)=O(n),注意,這里的n不是具體的數值N,不要以為查詢了100次就是O(100),這是錯的,這里只是為了方便理解(前面說了,時間復雜度并不是單指耗時,下同),
時間復雜度O(logn)理解:
一般的查找都是O(n),但是如果通過演算法,可以使查找的時間復雜度降低,比如二分查找,像上面解釋O(n)的例子中,采用二分查找的話,是不是就是個log(O(n))的對數數學模型,所以其時間復雜度為O(logn),
時間復雜度O(n^2)理解:
這里拿冒泡排序對某個陣列進行有序排序舉例,在冒泡排序中,分為獲取值、對該值進行排序、重復取值排序三個步驟,其中取值時間復雜度為O(1),則在N個數中進行該值的比較排序,則為N*O(1)=O(n)時間復雜度,這時候還沒有獲取到有序陣列,必須對這N個數重復進行取值、排序,執行N次,故時間復雜度為N * N * O(1)=O(n^2),

放在最后還是那句話,作為一個初學的筆者,同學們在看筆記的時候一定要本著一個懷疑的態度來看,來思考寫的對不對,只有自己確認過的才是可以相信.筆記有誤支出,請見諒.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/86615.html
標籤:Linux
上一篇:sed 命令備忘
