
進程(process):
狹義定義:進程就是一段程序的執(zhí)行過程例如啟動的某個app。
廣義定義:進程是一個具有獨立功能的程序關(guān)于某個數(shù)據(jù)集合的一次運行活動。它是操作系統(tǒng)動態(tài)執(zhí)行的基本單元,在傳統(tǒng)的操作系統(tǒng)中,進程即是基本的分配單元,也是基本的執(zhí)行單元。
1)進程是一個實體,每個進程都有自己的地址空間,一般情況下,包含文本區(qū)域、數(shù)據(jù)區(qū)域、堆棧
2)進程是執(zhí)行中的程序,程序是一個沒有生命的實體,只有處理器賦予程序生命時,它才能成為一個活動的實體,我們稱之為進程
3)進程本身不會運行,是線程的容器。線程不能單獨執(zhí)行,必須組成進程
4)一個程序至少有一個進程,一個進程至少有一個線程
5)對于操作系統(tǒng)來講,一個任務(wù)就是一個進程,比如開一個瀏覽器就是啟動一個瀏覽器進程。打開一款app就是打開一個進程,例如打開香哈就是運行了一個進程。
6)有些進程還不止同時做一件事情。比如打開香哈,它可以同時進行看視頻并且回復用戶評論,在一個進程內(nèi)部,要同時干多件事情。
進程狀態(tài):(三狀態(tài))
- 就緒:獲取出CPU外的所有資源、只要處理器分配資源就可以馬上執(zhí)行
- 運行:獲得處理器分配的資源,程序開始執(zhí)行
- 阻塞:當程序條件不夠的時候,需要等待提交滿足的時候才能執(zhí)行。

進程狀態(tài):(五態(tài)模型)對于一個實際的系統(tǒng),進程的狀態(tài)及其轉(zhuǎn)換更為復雜。引入新建態(tài)和終止態(tài)構(gòu)成了進程的五態(tài)模型。
- 創(chuàng)建狀態(tài):進程在創(chuàng)建時需要申請一個空白PCB,向其中填寫控制和管理進程的信息,完成資源分配。如果創(chuàng)建工作無法完成,比如資源無法滿足,就無法被調(diào)度運行,把此時進程所處狀態(tài)稱為創(chuàng)建狀態(tài)
- 就緒狀態(tài):進程已經(jīng)準備好,已分配到所需資源,只要分配到CPU就能夠立即運行
- 執(zhí)行狀態(tài):進程處于就緒狀態(tài)被調(diào)度后,進程進入執(zhí)行狀態(tài)
- 阻塞狀態(tài):正在執(zhí)行的進程由于某些事件(I/O請求,申請緩存區(qū)失敗)而暫時無法運行,進程受到阻塞。在滿足請求時進入就緒狀態(tài)等待系統(tǒng)調(diào)用
- 終止狀態(tài):進程結(jié)束,或出現(xiàn)錯誤,或被系統(tǒng)終止,進入終止狀態(tài)。無法再執(zhí)行

線程:
1)一個進程中至少有一個線程,不然就沒有存在的意義
2)在一個進程內(nèi)部,要同時干多件事情,就需要同時運行多個子任務(wù),我們把進程內(nèi)的這些子任務(wù)叫做線程
3)多線程就是為了同步完成多項任務(wù)(在單個程序中同時運行多個線程完成不同的任務(wù)和工作),不是為了提高運行效率,而是為了提高資源使用效率來提高系統(tǒng)的效率
4)一個簡單的比喻,多線程就像是火車上的每節(jié)車廂,而進程就是火車
5)線程是程序執(zhí)行流的最小單元。一個標準的線程由當前的線程ID、當前指令指針、寄存器和堆棧組成
6)同一個進程中的多個線程之間可以并發(fā)執(zhí)行
線程狀態(tài):
1)就緒:指線程具備運行的所有條件,邏輯上可以運行,在等待處理機
2)運行:指線程占用處理機正在運行
3)阻塞:線程在等待一個事件,邏輯上不可執(zhí)行
如果我們要同時執(zhí)行多個任務(wù)怎么辦?
1)啟動多個進程,每個進程雖然只有一個線程,但是多個進程可以一塊執(zhí)行多個任務(wù)
2)啟動一個進程,在一個進程內(nèi)啟動多個線程,這樣多個線程也可以一塊執(zhí)行多個任務(wù)
多任務(wù):
1)一邊瀏覽網(wǎng)頁、一邊聽歌、一邊看電影;這就是多任務(wù)。

協(xié)程:
協(xié)程是一種用戶態(tài)的輕量級線程,協(xié)程的調(diào)度完全由用戶控制(進程和線程都是由cpu 內(nèi)核進行調(diào)度)。協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非??臁?br>
對于 進程、線程,都是有內(nèi)核進行調(diào)度,有 CPU 時間片的概念,進行 搶占式調(diào)度(有多種調(diào)度算法)
對于 協(xié)程(用戶級線程),這是對內(nèi)核透明的,也就是系統(tǒng)并不知道有協(xié)程的存在,是完全由用戶自己的程序進行調(diào)度的,因為是由用戶程序自己控制,那么就很難像搶占式調(diào)度那樣做到強制的 CPU 控制權(quán)切換到其他進程/線程,通常只能進行 協(xié)作式調(diào)度,需要協(xié)程自己主動把控制權(quán)轉(zhuǎn)讓出去之后,其他協(xié)程才能被執(zhí)行到。
goroutine 和協(xié)程區(qū)別
本質(zhì)上,goroutine 就是協(xié)程。 不同的是,Golang 在 runtime、系統(tǒng)調(diào)用等多方面對 goroutine 調(diào)度進行了封裝和處理,當遇到長時間執(zhí)行或者進行系統(tǒng)調(diào)用時,會主動把當前 goroutine 的CPU (P) 轉(zhuǎn)讓出去,讓其他 goroutine 能被調(diào)度并執(zhí)行,也就是 Golang 從語言層面支持了協(xié)程。Golang 的一大特色就是從語言層面原生支持協(xié)程,在函數(shù)或者方法前面加 go關(guān)鍵字就可創(chuàng)建一個協(xié)程。
其他方面的比較
內(nèi)存消耗方面
每個 goroutine (協(xié)程) 默認占用內(nèi)存遠比 Java 、C 的線程少。
goroutine:2KB(官方)
線程:8MB(參考網(wǎng)絡(luò))線程和 goroutine 切換調(diào)度開銷方面
線程/goroutine 切換開銷方面,goroutine 遠比線程小
線程:涉及模式切換(從用戶態(tài)切換到內(nèi)核態(tài))、16個寄存器、PC、SP...等寄存器的刷新等。
goroutine:只有三個寄存器的值修改 - PC / SP / DX.
