什么是進(jìn)程和線程俊犯?
進(jìn)程是應(yīng)用程序的啟動(dòng)實(shí)例,進(jìn)程擁有代碼和打開的文件資源伤哺、數(shù)據(jù)資源燕侠、獨(dú)立的內(nèi)存空間。
線程從屬于進(jìn)程立莉,是程序的實(shí)際執(zhí)行者绢彤,一個(gè)進(jìn)程至少包含一個(gè)主線程,也可以有更多的子線程蜓耻,線程擁有自己的椕2埃空間。
對(duì)操作系統(tǒng)而言刹淌,線程是最小的執(zhí)行單元饶氏,進(jìn)程是最小的資源管理單元。無論是進(jìn)程還是線程有勾,都是由操作系統(tǒng)所管理的疹启。
線程的狀態(tài)
線程具有五種狀態(tài):初始化、可運(yùn)行蔼卡、運(yùn)行中喊崖、阻塞、銷毀
線程之間是如何進(jìn)行協(xié)作的呢?
最經(jīng)典的例子是生產(chǎn)者/消費(fèi)者模式荤懂,即若干個(gè)生產(chǎn)者線程向隊(duì)列中系欸如數(shù)據(jù)茁裙,若干個(gè)消費(fèi)者線程從隊(duì)列中消費(fèi)數(shù)據(jù)。
生產(chǎn)者/消費(fèi)者模式的性能問題是什么势誊?
- 涉及到同步鎖
- 涉及到線程阻塞狀態(tài)和可運(yùn)行狀態(tài)之間的切換
- 設(shè)置到線程上下文的切換
什么是協(xié)程呢呜达?
協(xié)程(Coroutines)是一種比線程更加輕量級(jí)的存在,正如一個(gè)進(jìn)程可以擁有多個(gè)線程一樣粟耻,一個(gè)線程可以擁有多個(gè)協(xié)程查近。
協(xié)程不是被操作系統(tǒng)內(nèi)核所管理的,而是完全由程序所控制挤忙,也就是在用戶態(tài)執(zhí)行霜威。這樣帶來的好處是性能大幅度的提升,因?yàn)椴粫?huì)像線程切換那樣消耗資源册烈。
協(xié)程不是進(jìn)程也不是線程戈泼,而是一個(gè)特殊的函數(shù),這個(gè)函數(shù)可以在某個(gè)地方掛起赏僧,并且可以重新在掛起處外繼續(xù)運(yùn)行大猛。所以說,協(xié)程與進(jìn)程淀零、線程相比并不是一個(gè)維度的概念挽绩。
一個(gè)進(jìn)程可以包含多個(gè)線程,一個(gè)線程也可以包含多個(gè)協(xié)程驾中。簡(jiǎn)單來說唉堪,一個(gè)線程內(nèi)可以由多個(gè)這樣的特殊函數(shù)在運(yùn)行,但是有一點(diǎn)必須明確的是肩民,一個(gè)線程的多個(gè)協(xié)程的運(yùn)行是串行的唠亚。如果是多核CPU,多個(gè)進(jìn)程或一個(gè)進(jìn)程內(nèi)的多個(gè)線程是可以并行運(yùn)行的持痰,但是一個(gè)線程內(nèi)協(xié)程卻絕對(duì)是串行的灶搜,無論CPU有多少個(gè)核。畢竟協(xié)程雖然是一個(gè)特殊的函數(shù)工窍,但仍然是一個(gè)函數(shù)占调。一個(gè)線程內(nèi)可以運(yùn)行多個(gè)函數(shù),但這些函數(shù)都是串行運(yùn)行的移剪。當(dāng)一個(gè)協(xié)程運(yùn)行時(shí),其它協(xié)程必須掛起薪者。
進(jìn)程纵苛、線程、協(xié)程的對(duì)比
- 協(xié)程既不是進(jìn)程也不是線程,協(xié)程僅僅是一個(gè)特殊的函數(shù)攻人,協(xié)程它進(jìn)程和進(jìn)程不是一個(gè)維度的取试。
- 一個(gè)進(jìn)程可以包含多個(gè)線程,一個(gè)線程可以包含多個(gè)協(xié)程怀吻。
- 一個(gè)線程內(nèi)的多個(gè)協(xié)程雖然可以切換瞬浓,但是多個(gè)協(xié)程是串行執(zhí)行的,只能在一個(gè)線程內(nèi)運(yùn)行蓬坡,沒法利用CPU多核能力猿棉。
- 協(xié)程與進(jìn)程一樣,切換是存在上下文切換問題的屑咳。
上下文切換
進(jìn)程的切換者是操作系統(tǒng)萨赁,切換時(shí)機(jī)是根據(jù)操作系統(tǒng)自己的切換策略,用戶是無感知的兆龙。進(jìn)程的切換內(nèi)容包括頁全局目錄杖爽、內(nèi)核棧、硬件上下文紫皇,切換內(nèi)容保存在內(nèi)存中慰安。進(jìn)程切換過程是由“用戶態(tài)到內(nèi)核態(tài)到用戶態(tài)”的方式,切換效率低聪铺。
線程的切換者是操作系統(tǒng)化焕,切換時(shí)機(jī)是根據(jù)操作系統(tǒng)自己的切換策略,用戶無感知计寇。線程的切換內(nèi)容包括內(nèi)核棧和硬件上下文锣杂。線程切換內(nèi)容保存在內(nèi)核棧中。線程切換過程是由“用戶態(tài)到內(nèi)核態(tài)到用戶態(tài)”番宁, 切換效率中等元莫。
協(xié)程的切換者是用戶(編程者或應(yīng)用程序),切換時(shí)機(jī)是用戶自己的程序所決定的蝶押。協(xié)程的切換內(nèi)容是硬件上下文踱蠢,切換內(nèi)存保存在用戶自己的變量(用戶棧或堆)中棋电。協(xié)程的切換過程只有用戶態(tài)茎截,即沒有陷入內(nèi)核態(tài),因此切換效率高赶盔。
協(xié)程的開銷為什么遠(yuǎn)遠(yuǎn)小于線程的開銷呢企锌?