目錄
- 一、 進程
- 1.1 PID(進程標識符)
- 1.2 內存指針
- 1.3 文件描述符表
- 1.4 狀態
- 1.5 優先級
- 1.6 記賬信息
- 1.7 上下文
- 二、線程
- 三、總結:進程和線程之間的區別(非常非常非常重要,面試必考題)
一、 進程
簡單來介紹一下什么是進程,在我的理解中我是把每一個任務都當成一個進程,例如:我打開了電腦微信APP就是一個任務,也是一個進程。
這里的每一個任務都是進程,然后通過C++中的結構體,這里叫做PCB(進程控制塊)來描述一個進程,然后通過鏈表將這些PCB給連接起來,當我們查看是就是遍歷該鏈表,將存儲的信息展示出來,當打開或是刪除一個進程時,只需要在鏈表的頭或尾進行插入和刪除即可,每個進程都有一個結構體PCB,然后通過數據結構組織起來就形成上面的結果。
相比大家已經對PCB(進程控制塊)有了一點了解,簡單來說就是來描述一個進程的結構體,當然了,在結構體中是不是還有相當多的屬性來組成這個結構體的,例如:上圖中的狀態、CPU…等都是PCB中的一個屬性,也是我們接下來要學習的重點,這里我們學習PCB中的7大屬性。
分別是:
- PID(進程標識符)
- 內存指針
- 文件描述符
- 狀態
- 優先級
- 記賬信息
- 上下文
所以說一個任務是一個進程,進程也就是系統分配資源的基本單位。
接下來讓我們進入真正學習進程的內容了。
1.1 PID(進程標識符)
這個PID賊好理解,就記住PID的一個身份證或是一個數字,專門用來標記這個進程的,當然了,身份證是不重復的,這里的PID也不會有重復的同時出現,當你要使用該進程時,操作系統就會根據你的這個PID來迅速拿到這個進程。
上圖可以看到,每一個進程都有一個PID,且是唯一的。
1.2 內存指針
按我的理解來說就是在創建該進程時,需要消耗一定的系統資源的,其中內存就是一種非常重要的資源,在整個電腦中,內存就那么大一點能讓你隨意使用嗎?那肯定當然不是啦。
先從系統這里進行申請,系統分配給你一塊,你才是可以使用,由內存指針指定了一塊內存資源的區域,表示了你這個進程呀就在這塊區域進行活動,且不能超出該區域,每個進程都必須使用自己申請到時候內存(一畝三分地)。
由于內存指針是進程創建時就已經開辟好了的,這里我們無法進行圖片展示
總結來說:內存指針就是描述一個進程都能使用哪些內存資源的。
1.3 文件描述符表
內核為每個進程維護一個文件描述符表,該表記錄了文件描述符的相關信息,包括文件描述符、指向打開文件表中記錄的指針。
簡單來說就是文件描述符表描述了一個進程對于內存資源使用的情況。
上圖中的CPU、內存、以及磁盤都是文件描述符表對于該進程對內存資源使用的多少進行了統計。
1.4 狀態
狀態又分為阻塞狀態和運行狀態,在系統調度中心,若是要讓 這個進程到CPU上進行執行就會將它的狀態轉變為就緒狀態在執行中轉變為運行狀態,但是當不想讓該進程進行執行時只需要將它轉變為阻塞狀態即可。
可以清楚的看到,這些狀態一共有兩種,一種是正在運行狀態,一種是已掛起狀態,已掛起狀態也可以叫做阻塞狀態。
1.5 優先級
優先級也很簡單,我想問一下大家,當年同時運行王者榮耀打團時和微信聊天的時候,你要是CPU會先調度誰先來進行運行,很顯然的我會先運行王者榮耀,但是計算機并不知道要先運行哪一個該怎么辦?
這個時候就需要我們的優先級站出來了,優先級高的進程會優先進入CPU進行執行。
1.6 記賬信息
簡單來說就是針對每一個進程占據了多少CPU時間,進行了一個統計,然后會根據這個統計結果來進一步的調整調度的策略,確保在下一輪調整后的調度中,確保每一個進程都能進入CPU進行調度.
總結來說就是通過記賬信息來進行動態的優化,讓每一個進程都能進入CPU進行執行。
1.7 上下文
我們都知道在進程的調度中可能一個進程還沒有執行完就被系統調度走了,難道下一次被調度回來時要重新執行前面執行了一半的嗎?很顯然不是這樣的。
其實上下文有點向我們玩小游戲中的讀檔和存檔,當打到第9關卡時不想玩了,就保存文檔到上下文,當我們下一次想玩的時候在通過讀取存檔就可以繼續上一次的關卡來進行了。
當進行進入CPU執行后被調度走時,會將當前處理的數據放在上下文中,當下一次重新被調度回來時在通過讀取上下文信息進行繼續執行。
二、線程
通過上面的學習我們知道了什么是進程,運行一個任務就是一個進程,那么什么是線程呢?可以理解為一個進程可以由一個或多個線程組成,系統在調度時會將一個進程分成多個線程來執行,當所有線程執行完,也就代表著該進程執行完了。
并且由于進程中進行頻繁的創建和銷毀時,會產生很大的開銷(主要體現在資源的申請和釋放上面),為什么進程會比線程開銷大呢,舉個例子:我打開王者榮耀就是一個進程,在剛進入加載界面時是不是會很慢,因為它要加載的數據很多很多,但是當我們進入后打開英雄界面或是匹配界面為什么會快秒出來呢,打開英雄界面就相當于是一個線程,匹配界面也是一個線程,當我關閉該界面(銷毀線程時)處理很快,但是我要是關閉一個界面就需要重啟一下游戲(進程)時,就知道多痛苦了,也可以看出來,一個進程可以由多個線程組合來完成工作,線程也可以稱之為"輕量級進程"。
因此說:線程是系統進行調度的基本單位。
下圖描述了進程和線程的關系。、
每一個進程在內存空間開辟一塊屬于自己的內存,他們之間相互獨立,也叫做內存管理
第二個圖片可以看出來,多個線程指向了同一塊內存空間,而進程也是由一塊空間組成,所以說進程由一個或多個線程構成,只是構成該進程的每一個線程的內存指針相同指向同一塊區域,同時線程的文件描述符表也相同都是進程對內存資源的使用情況,當然了進程中其它的屬性線程也都有,除了內存指針不同和文件描述符表不同之外,其它是屬性和進程一樣各不相同。
三、總結:進程和線程之間的區別(非常非常非常重要,面試必考題)
1.進程時系統進行資源分配時的基本單位,線程是系統調度執行時的基本單位
2.進程是包含線程的,一個進程可以由一個或多個線程組成
3.進程由一個或多個PCB組成,一個PCB包含的屬性有PID、內存指針、文件描述符表、狀態、優先級、記賬信息以及上下文等諸多屬性。
4…每個進程都有屬于自己的資源,但同一個進程中的線程會共用這一份資源(該進程中線程的內存空間和文件描述符表相同)。
5.同一個進程中的線程也是一個獨立的執行流,可以執行代碼,并且可以單獨的參與到CPU的調度中(該進程中 ,線程的PID,狀態,優先級,記賬信息,上下文相同的)。
6.進程和進程之間不會相互影響,因為他們的內存空間相互獨立,也叫做:內存管理
7.進程間也可以相互交換信息,但需要CPU開辟一塊公共空間用于交換,該過程叫做:進程間通信
8.同一個進程中的線程之間,可能會互相干擾,拋出異常,會影響到其它的線程,會把整個進程中的所有線程搞崩潰,從而引發線程安全問題。
9.同一個進程中的線程并不是越多越好,要能夠合適,達到最大效率,如果線程太多了,調度開銷也可能非常明顯。