一.進程和線程的區別
1.本質區別和所屬關系是什么?
進程是資源調度以及分配的基本單位。
線程是CPU調度的基本單位。
一個線程屬于一個進程,一個進程可以擁有多個線程。
2.地址空間和內存
進程擁有獨立的虛擬地址空間。
線程沒有獨立的地址空間;線程有棧,程序計數器(PC),本地存儲(LS) 等少量獨立空間。
系統會為每個進程分配不同的內存空間
系統不會為線程分配內存,線程所使用的資源來自所屬的進程資源。
3.并發性和健壯性
進程的并發性較低。
線程的并發性較高。
對于單個CPU,系統會把CPU運行時間劃分為多個時間段,再將時間段分配給各個線程執行。
在切換效率上,進程切換效率低,線程切換效率高,都會涉及到上下文的切換。
一個進程崩潰不會影響其他進程。
一個線程崩潰可能會導致整個進程崩潰 。
進程隔離性更強一些。
?二.操作系統中進程和線程的切換過程
1.進程由哪幾個部分構成?
task_struct
進程的地址空間? =? 代碼段___數據段___棧區____堆區
?2.上下文由哪幾個部分組成?
用戶級上下文
系統級上下文 = __進程標識符信息__進程現場信息__進程控制信息__系統內核棧
寄存器上下文(硬件上下文) = __CPU各寄存器的內容___進程的現場信息
?3.何時發生切換?
主動? ?=? 系統調用,產生軟中斷。
被動? ?=? 時間中斷
靠中斷來完成切換
4.現場信息存儲在哪里?
程序計數器(PC),寄存器,堆棧,進程/線程控制塊(PCB)
?5.進程/線程切換過程
保存當前進程的硬件上下文,修改當前進程的PCB,狀態由運行態變為就緒態或者阻塞態,加入相關隊列,調度另外一個進程,修改被調度進程的PCB,狀態變為運行態,把當前進程的存儲管理數據改為被調度進程的存儲管理信息(頁表,cache,TLB)__(這一小段線程沒有__線程不具備虛擬地址空間__共享進程的虛擬地址空間),恢復被調度進程的硬件上下文,讓PC指向新的進程代碼。
?三.系統調用的整個流程
1.系統調用是什么?干嘛的?
系統調用是內核給用戶程序提供的編程接口,內核具有最高的權限,可以直接訪問所有資源,用戶只能訪問受限制的資源,不能直接訪問內存,網絡,磁盤等硬件資源。
?大致的流程 = 應用程序--->函數庫---->系統調用--->內核
靠中斷使程序從用戶態切換到內核態或者從內核態切換到用戶態?
2.系統調用是否引起進程或者線程切換??
不會必然切換:很多系統調用(如
getpid()
、gettimeofday()
等)只是簡單地獲取信息,執行很快,不會導致進程或線程切換。可能導致切換:如果系統調用涉及阻塞操作(如
read()
、write()
、accept()
、sleep()
等),當前進程或線程因為等待I/O或資源而被阻塞,操作系統會把它掛起,調度其他進程或線程運行,這時就會發生切換。主動讓出CPU:有些系統調用(如
sched_yield()
、sleep()
)會主動讓出CPU,也會導致切換。
?3.系統調用引起中斷上下文切換
系統調用一定會引起用戶態到內核態的中斷上下文切換,但是否會引起進程或線程的切換,要看系統調用是否導致阻塞或主動讓出CPU。
4.系統調用的流程?
用戶態發起系統調用
應用程序通過調用庫函數(如C語言的read()
、write()
等)發起系統調用請求。陷入內核態
庫函數內部會使用特定的指令(如x86上的syscall
或int 0x80
)觸發軟中斷或陷入,CPU從用戶態切換到內核態。保存現場
CPU會保存當前用戶態的寄存器等現場信息,確保系統調用返回后能恢復原來的執行狀態。內核處理系統調用
操作系統根據系統調用號找到對應的內核服務例程,執行相應的內核代碼,完成所需的操作(如文件讀寫、進程管理等)。返回用戶態
系統調用執行完畢后,內核將結果返回給用戶程序,并通過特定的指令(如sysret
)切換回用戶態,恢復之前保存的現場。用戶程序繼續執行
用戶程序獲得系統調用的返回值,繼續后續的執行。
四.后臺進程有什么特點??
1.前臺進程是什么?有什么用?
運行在前臺的進程,終端是該進程的控制終端,終端關閉(SIGHUP),進程退出。
可接受終端輸入,并可以在終端輸出。
?2.后臺進程是什么?有什么用?
運行在后臺的進程,若在終端運行,終端關閉,進程可能退出。
不可以接受終端輸入,可以在終端輸出。
3.前后臺程序切換?
Ctrl + Z:可以將當前前臺運行的程序掛起,轉為后臺暫停狀態。
fg:用于將后臺的程序切換回前臺繼續運行。
bg:讓已經掛起的后臺程序在后臺繼續運行。
&:在命令末尾加上&,可以讓程序直接在后臺運行。
nohup:用于忽略SIGHUP信號,通常配合&一起使用,保證程序在終端關閉后依然運行。
Ctrl + D:用于斷開當前終端的session,相當于退出登錄。
?4.守護進程
?后臺進程的延申,脫離終端的后臺進程。
5.如何成為守護進程?
fork子進程令父進程退出,讓子進程被init進程接管,成為孤兒進程。
setsid()建立新的進程會話,使守護進程成為會話首進程,從而脫離與終端的關聯。
打開/dev/null,把0,1,2重新定向到/dev/null。
五.進程間通信有哪幾種方式
1.管道
單根管道是半雙工的,通常用于父子進程之間,通過pipe文件速度慢,容量有限。
2.FIFO?(有名/命名管道)
FIFO(First In First Out)有名管道是一種用于進程間通信(IPC)的機制。與匿名管道不同,有名管道有一個路徑名,存在于文件系統中,通常通過
mkfifo
命令或mkfifo()
系統調用創建。
3.消息隊列?
消息的連接表存儲在內核當中,獨立于進程,容量有限。
消息隊列的流程主要包括通過
msgget
創建隊列,使用msgsnd
發送消息,msgrcv
接收消息,最后用msgctl
管理或刪除隊列。?
4.共享內存?
多個進程共享的一塊存儲區,最快的一種IPC方式,需要和信號量配合使用。
共享內存的接口使用流程主要包括通過
shmget
創建共享內存,shmat
掛載到進程地址空間,進程間讀寫數據,最后用shmdt
分離和shmctl
刪除共享內存。?
5.信號?
信號是一種軟中斷,處理方式是忽略/捕獲/默認動作。
?6.信號量
信號量是一個計數器,主要用于進程/線程之間的同步和互斥。
?7.socket套接字
不局限于是否在同一個機器上。
?六.操作系統中進程調度策略
1.什么是進程調度?
調度對象
線程和進程相對于操作系統而言都是任務(task_struct)。
線程又稱為共享用戶虛擬地址空間的進程。
包含多個線程的進程稱之為線程組。
只有一個線程的進程稱為進程。
沒有用戶虛擬地址空間的進程稱之為內核線程。
用于絕對由誰(哪個或者哪幾個)獲得處理器的執行權?
進程狀態
就緒 -->|進程調度| 運行
運行 -->|時間片用完| 就緒運行 -->|io請求| 阻塞
阻塞 -->|io就緒| 就緒
?調度時機
主動調度(系統調用等待某個資源)。
周期調度(系統進程不主動讓出,內核依靠周期時鐘來搶占調度)。
喚醒搶占,創建新進程搶占,內核搶占。
2.進程調度有哪些算法??
先來先服務(FCFS)
從就緒隊列中存在時間最長的進程執行調度。
?短作業優先(SJF)
從就緒隊列中選擇估計運行時間最短的任務執行調度
高響應比優先?
FCFS和SJF的綜合;綜合考慮等待時間和估計運行時間來選擇執行調度。
時間片輪轉調度
?適用分時系統,為任務分配時間片,執行完時間片后放入就緒隊列。
優先級調度?
從就緒隊列中選擇優先級最高的若干任務執行調度。
優先級用來描述運行的緊迫程度。
多級反饋隊列?
時間片和優先級的綜合。
動態調整任務的優先級和時間片的大小,從而兼顧多方面的系統目標。