linux基本概念(一)----進程和線程

先給自己打個廣告,本人的微信公衆號正式上線了,搜索:張笑生的地盤,主要關注嵌入式軟件開發,足球等等,希望大家多多關注,有問題可以直接留言給我,一定盡心盡力回答大家的問題
在這裏插入圖片描述

一 why

今天這篇文章主要以基本概念爲主,沒有相關的源碼,可能看起來比較抽象和枯燥,但是我還是建議大家認真讀一讀這個文章,在讀的過程中多思考文章中提出的相關問題,這個對我們打好基礎至關重要,我們不能只停留在編寫代碼實現功能的層次上,我們也需要對一些底層的邏輯和概念有一個全面正確的認識。

進程和線程的概念非常重要,本篇博客來重點介紹兩者的概念。我們在實際開發過車中,經常會聽到這兩個詞,還包括"作業",“你開了幾個線程”,“創建了幾個進程”,“進程間通信”,“線程間同步”等等,如果我們不瞭解這些詞背後的概念,非常不利於我們閱讀代碼,也不利於編寫更優美的代碼的

二 what

1. 程序
在談進程和線程之前,我們先來看看什麼是程序?我們不同語言的軟件開發者,每天的工作/學習內容絕大部分,要麼是在看源代碼然後分析bug,要麼是在編寫源代碼(創造bug,這裏開個玩笑,因爲編寫的代碼的過程中很有可能有bug)。

ok,那麼這些源代碼就是一個個程序,它是一種靜態的狀態,存在我們的硬盤上,服務器server上,或者雲上。

所以結論就是,我們每天編寫或者閱讀的源代碼就是一個個程序,如下就是一段程序
在這裏插入圖片描述
2. 進程
a. 定義
進程是具有一定獨立功能的程序在一個數據集合上的一次動態執行過程它是動態的,包括創建,調度,執行和消亡。希望我們認真思考一下這個定義。
我想大家在閱讀“具有一定獨立功能的程序在一個數據集合上”這一句話的時候,應該會一臉茫然,這句話看着每個詞都很簡單,但是組合在一起表達什麼意思時,就不清楚了。我們知道一個基本公式,就是程序 = 算法 + 數據結構,所以一個程序一定是對某些數據進行處理,這些數據是一個廣義意義上的概念,並不單單指1,2,3…等等這樣的數據。因此白話來說,程序開始運行,對數據進行分析處理的過程就是一個進程
b. 進程和程序的聯繫

1. 程序是產生進程的基礎
2. 程序的每次執行構成不同的進程
3. 進程是程序功能的體現
4. 通過多次執行,一個程序可對應多個進程;通過調用的關係,一個進程可包括多個程序

c. 進程和程序的區別

1. 進程是動態的,程序是靜態的:程序是有序代碼的集合,進程是程序的執行,進程有和心態/用戶態
2. 進程是暫時的,而程序是永久的,進程是一個狀態變化的過程,程序可長久保存
3. 進程和程序的組成不同,進程的組成包括程序,數據和進程控制塊

比喻理解進程和程序的區別

1. 有一位計算機科學家,他要給女兒做一個生日蛋糕,於是他去找了一本菜譜,跟着菜譜學做蛋糕
 菜譜 = 程序  廚師 = CPU
 原料 = 數據(不包含在程序裏面); 做菜的過程 = 進程
2. 正在做蛋糕的時候,突然他的小兒子跑來,說他的手被扎破了,於是科學家又去找一本醫療手冊書籍,給小兒子處理傷口,處理完之後再回來繼續做蛋糕
醫療手冊書籍 = 新程序 給小兒子處理傷口 = 新進程,從前進程切換到新進程,進程切換
處理完之後再回來繼續做蛋糕 = 進程恢復

在這裏插入圖片描述
d. 進程的組成

1)代碼段
(2)用戶數據段
(3)系統數據段
	包括進程控制塊,CPU寄存器值,堆棧,這樣來看,linux中進程的概念和ucos任務的概念相類似,ucos中的任務也包括任務控制塊,CPU寄存器值以及堆棧
	進程標識信息:
		(1) 進程控制塊(pcb, process control block),可以完全參照ucos的tcb來理解
		它是操作系統管理控制進程運行所用的信息集合,PCB是進程存在的唯一標識
			a. 進程標識 PID
			b. 進程用戶,標識進程是由哪個用戶創建的
			c. 進程狀態,優先級
			d. 文件描述符表
	處理機狀態信息保存區
		(1) CPU寄存器值,PC寄存器,SP寄存器等等
		(2) 堆棧
	進程控制信息
		調度和狀態信息
		進程間通信信息
		存儲管理信息
		進程所用資源

e. 進程類型

(1) 交互進程 在shell下啓動,在前臺運行,也可以在後臺運行
(2) 批處理進程 和在終端無關,被提交到一個作業隊列中以便順序執行
(3) 守護進程 和終端無關,一直在後臺運行

f. 進程的狀態

進程的生命週期
	進程創建
		引起進程創建的3個主要事件
			系統初始化時,即是INIT進程
			用戶請求創建一個新進程
			正在運行的進程執行了創建進程的系統調用
	進程運行
	進程等待
	進程喚醒
	進程結束
運行態 進程正在運行,或者準備運行
等待態 進程在登臺某個事件的發生
停止態 進程被終止,收到信號後可繼續運行
死亡態 已經終止的進程,但pcb沒有被釋放

3. 線程
自從60年代最開始提出進程的概念概念,在操作系統中一直都是以進程作爲獨立運行的基本單位,到了80年代,人們提出了更小的能獨立運行的基本單位 ---- 線程
那麼問題是:爲什麼需要線程?請思考下面一個生活中的例子
a. 舉例
從例子引入線程的概念,編寫一個MP3播放軟件
實現方案1:這個應該是很多人第一時間第一反應想到的方案

main()
{
	while(1)
	{
		read();           // IO 速度
		decompress();     // CPU
		play();
	}
}

這個方案從功能角度來看,確實可以實現目的,但是這個方案有什麼不足呢?由於read,decompress,play是順序執行的,而每個執行的效率和時間由每個函數的內部實現決定,如果read函數因爲種種原因,比如IO速度較慢,這樣play函數就不能及時運行,表現就是某段時間沒有任何音頻輸出,造成播放不連續。

實現方案2:這是一種多進程實現方案,如果我們沒有線程的概念,爲了解決方案1的缺點,我們會設計多個進程,每個進程完成一個動作

//read				   //decompress             //play
main()                 main()                   main()
{                      {                        {
	while(1)           		while(1)                 while(1)
	{                       {                        {
		read();					decompress();            play();
	}						}                        }
}						}						}

這種方案確實是一種可行方案,解決了方案1中的效率問題。但是這個方案的缺點是什麼呢,我們知道進程的創建需要很多開銷,比如內存。不同進程之間的內存空間是相互獨立的,不能互相訪問,這樣上面的三個進程之間的數據共享也是一個問題,需要實現進程間通信
實現方案3:我們需要一種新的實體,這個實體需要滿足如下特點

實體之間可以併發地執行
實體之間共享相同的地址空間
main()
{
		read();           // IO 速度
		decompress();     // CPU
		play();
}
read()
{
	while(1)
	{
	}
}
decompress()
{
	while(1)
	{
	}
}
play()
{
	while(1)
	{
	}
}

b. 定義

線程是進程當中的一條執行流程,它是進程的一部分

c. 線程的優點和缺點

優點
	一個進程中可以同時存在多個線程
	各個線程之間可併發執行
	各個線程之間可以共享地址空間和文件等資源
缺點
	一個線程崩潰,會導致其所屬進程的所有線程崩潰

在這裏插入圖片描述

既然程有上面的缺點,那麼何時使用多線程?何時使用多進程

主要是從性能和安全性來考慮,如果考慮性能的瓶頸的話,使用線程,如果從安全性考慮的話,使用進程
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章