今天看到網上一篇介紹linux進程調度的文章(https://blog.csdn.net/21cnbao/article/details/77505330),裏面提了一些問題,本文試着進行解答。linux
本文會持續更新。數據結構
1. Linux進程和線程如何建立、退出?進程退出的時候,本身沒有釋放的資源(如內存沒有free)會怎樣?多線程
解答:負載均衡
Linux進程經過fork來建立函數
Linux線程經過pthread_create建立,性能
2. 什麼是寫時拷貝?優化
解答:spa
寫時拷貝(copy-on-write, COW)就是等到修改數據時才真正分配內存空間,這是對程序性能的優化,能夠延遲甚至是避免內存拷貝,固然目的就是避免沒必要要的內存拷貝。.net
Linux 的fork系統調用就使用了寫時拷貝技術,具體細節以下:線程
如今有一個父進程P1,這是一個主體,那麼它是有靈魂也是有身體的。如今在其虛擬地址空間(有相應的數據結構表示)上有:正文段,數據段,堆,棧這四個部分,相應地,內核要爲這四個部分分配給自的物理塊。即正文段塊、數據段塊、堆塊、棧塊。
內核:
(1) 複製P1的正文段,數據段,堆,棧這四個部分,注意是其內容相同。
(2) 爲這四個部分分配物理塊,P2的:正文段(爲P1的正文段的物理塊,其實就是不爲P2分配正文段塊,讓P2的正文段指向P1的正文段塊),數據段(P2本身的數據段塊,爲其分配對應的塊),堆(P2本身的堆塊),棧(P2本身的棧塊)。以下圖所示,同左到右大的方向箭頭表示複製內容:
寫時複製技術:內核只爲新生成的子進程建立虛擬空間結構,它們複製於父進程的虛擬空間結構,可是不爲這些段分配物理內存,它們共享父進程的物理空間,當父子進程中有更改相應的段的行爲發生時,再爲子進程相應的段分配物理空間。
vfork的作法更加簡單粗暴,內核連子進程的虛擬地址空間也不建立了,直接共享了父進程的虛擬空間,固然了,這種作法就順水推舟的共享了父進程的物理空間
傳統的fork()系統調用直接把全部的資源複製給新建立的進程。這種實現過於簡單而且效率低下,由於它拷貝的數據也許並不共享,更糟的狀況是,若是新進程打算當即執行一個新的映像,那麼全部的拷貝將是無用功。
Linux的fork()使用寫時拷貝(copy-on-write)頁實現。寫時拷貝是一種能夠推遲甚至免除拷貝數據的技術。內核此時並不複製整個地址空間,而是讓父進程和子進程共享一個拷貝。只有在須要寫入的時候,數據纔會複製,從而使各個進程擁有各自的拷貝。也就是說,資源的複製只有在須要寫入的時候才進行,在此以前,只是以只讀方式共享。這種技術使地址空間的頁的拷貝被推遲到實際發生寫入的時候。
3. Linux的線程如何實現,與進程的本質區別是什麼?
解答:
進程是資源分配和管理的單位,線程是調度的基本單位,進程有獨立的地址空間,擁有PCB,其中包含進程標識符(非負整數)、進程資源、進程調度信息、進程間通訊相關資源、處理機狀態(便於調度後恢復原狀態)等,線程具備單獨的堆棧和寄存器,保存本身容許的相關上下文,具備TCB。各線程還共享如下進程資源和環境:
1)文件描述符表
2)每種信號的處理方式(SIG_IGN,SIG_DFL,用戶自定義)
3)當前工做目錄
4)用戶id和組id
但有些資源是線程獨享的:
1)線程id
2)上下文,包括各類寄存器的值,程序計數器和棧指針
3)棧空間
4)errno變量
5)信號屏蔽字
6)調度優先級
4. Linux可否知足硬實時的需求?
5. 進程如何睡眠等資源,此後又如何被喚醒?
6. 進程的調度延時是多少?
7. 調度器追求的吞吐率和響應延遲之間是什麼關係?CPU消耗型和I/O消耗型進程的訴求?
8. Linux怎麼區分進程優先級?實時的調度策略和普通調度策略有什麼區別?
9. nice值的做用是什麼?nice值低有什麼優點?
10. Linux能夠被改形成硬實時嗎?有什麼方案?
11. 多核、多線程的狀況下,Linux如何實現進程的負載均衡?
12. 這麼多線程,究竟哪一個線程在哪一個CPU核上跑?有沒有辦法把某個線程固定到某個CPU跑?
13. 多核下如何實現中斷、軟中斷的負載均衡?
14. 如何利用cgroup對進行進程分組,並調控各個group的CPU資源?
15. CPU利用率和CPU負載之間的關係?CPU負載高必定用戶體驗差嗎?