您好,登錄后才能下訂單哦!
這篇文章主要介紹“go語言中線程和進程的區(qū)別有哪些”,在日常操作中,相信很多人在go語言中線程和進程的區(qū)別有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”go語言中線程和進程的區(qū)別有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
區(qū)別:1、線程是程序執(zhí)行的最小單位,而進程是操作系統(tǒng)分配資源的最小單位。2、一個進程由一個或多個線程組成,線程是一個進程中代碼的不同執(zhí)行路線。3、線程上下文切換比進程上下文切換要快得多。4、進程切換需要的資源很最大,效率很低;線程切換需要的資源一般,效率一般。5、進程擁有自己的堆棧,進程之間不共享堆棧;線程擁有自己的棧,共享堆。
進程
是一個具有一定獨立功能的程序在一個數(shù)據(jù)集上的一次動態(tài)執(zhí)行過程
是操作系統(tǒng)進行資源分配和調(diào)度的一個獨立單位
是應(yīng)用程序的運行的載體
線程
線程是程序執(zhí)行中一個單一的順序控制流程
是程序執(zhí)行流的最小單位
是處理器調(diào)度和分配的基本單位
一個進程可以有一個或多個線程
各個線程之間共享程序的內(nèi)存空間
大部分操作系統(tǒng)(Windows、Linux)的任務(wù)調(diào)度采用時間片輪轉(zhuǎn)的搶占式調(diào)度方式。
該調(diào)度方式如下:
在一個進程中,當(dāng)一個線程任務(wù)執(zhí)行幾毫秒后,會由操作系統(tǒng)內(nèi)核進行調(diào)度
通過硬件的計數(shù)器中斷處理器,讓該線程強制暫停并將該線程的寄存器放入內(nèi)存中
通過查看線程列表決定接下來執(zhí)行哪一個線程
然后從內(nèi)存中恢復(fù)該線程的寄存器,最后恢復(fù)該線程的執(zhí)行,從而去執(zhí)行下一個任務(wù)
這種方式保證了每個線程輪流執(zhí)行,由于CPU的執(zhí)行效率非常高,時間片非常短,在各個任務(wù)之間快速地切換,給人的感覺就是多個任務(wù)在同時進行,這就是我們說的并發(fā)。
線程是程序執(zhí)行的最小單位,而進程是操作系統(tǒng)分配資源的最小單位
一個進程由一個或多個線程組成,線程是一個進程中代碼的不同執(zhí)行路線
線程上下文切換比進程上下文切換要快得多
進程切換需要的資源很最大,效率很低;線程切換需要的資源一般,效率一般。
進程擁有自己的堆棧,進程之間不共享堆棧,由操作系統(tǒng)調(diào)度
線程擁有自己的棧,共享堆,也是由操作系統(tǒng)調(diào)度
多核處理器是指在一個處理器上集成了多個運算核心從而提高計算能力。也就是有多個真正并行計算的處理核心,每一個處理核心對應(yīng)一個內(nèi)核線程。
內(nèi)核線程
每一個處理核心對應(yīng)一個內(nèi)核線程。
比如:
單核處理器對應(yīng)一個內(nèi)核線程
雙核處理器對應(yīng)兩個內(nèi)核線程
四核處理器對應(yīng)四個內(nèi)核線程
內(nèi)核線程(Kernel Thread,KLT)就是直接由操作系統(tǒng)內(nèi)核支持的線程。該線程由內(nèi)核來完成線程切換,內(nèi)核通過操作調(diào)度器對線程進行調(diào)度,并負(fù)責(zé)將線程的任務(wù)映射到各個處理器上。
目前處理器都采用了超線程技術(shù)將一個 物理處理核心模擬成兩個邏輯處理核心,也就是兩個內(nèi)核線程。
所以我們看到的電腦一般都是雙核四線程、四核八線程。
在操作系統(tǒng)中我們看到CPU數(shù)量是實際物理CPU數(shù)量的兩倍,如雙核四線程可以看到4CPU。
如我當(dāng)前編寫文章的這臺mbp就是i7 6核12線程:
程序一般不會直接使用內(nèi)核線程,而是使用內(nèi)核線程的一種高級接口—輕量級進程(Lightweight Process,LWP),也就是我們常說的線程。
協(xié)程(Coroutines)基于線程之上,比線程更加輕量級。一個線程可以擁有多個協(xié)程。
協(xié)程的目的
傳統(tǒng)應(yīng)用中一般有會給網(wǎng)絡(luò)請求創(chuàng)建一個線程去完成業(yè)務(wù)邏輯。如果是多個請求,就會創(chuàng)建多個線程來出來。
如果遇到很耗時的I/O行為,線程就會一直處于阻塞狀態(tài),如果很多線程都是出于這種空閑狀態(tài)(等待該線程執(zhí)行完成才能執(zhí)行),這樣就會造成資源應(yīng)用不徹底,系統(tǒng)的吞吐能力下降。
最常見的很耗時的I/O行為比如JDBC,CPU會一直等待數(shù)據(jù)I/O操作的返回,這時線程根本沒有利用CPU去做運算,而是處于空閑狀態(tài)。同時使用過多的線程,也會帶來更多的上下文切換開銷。
解決上述問題有兩個方案:
單線程加上異步回調(diào)
比如Node.js、Java的Vert.x
協(xié)程
協(xié)程的目的就是當(dāng)出現(xiàn)長時間I/O操作時,讓出當(dāng)前的協(xié)程調(diào)度,執(zhí)行下一個任務(wù),來消除ContexSwith的開銷
協(xié)程的特點
線程切換由操作系統(tǒng)負(fù)責(zé)調(diào)度,協(xié)程由用戶自己調(diào)度,因此減少了上下文切換,提高了效率
線程默認(rèn)Stack大小為1M,而協(xié)程更輕量,接近1K。因此可以在相同的內(nèi)存中開啟更多的協(xié)程
由于協(xié)程在同一線程上,因此可以避免競爭關(guān)系二使用鎖
適用于被阻塞且需要大量并發(fā)的場景。但不適用于大量計算的多線程
協(xié)程的原理
協(xié)程的流程:
當(dāng)出現(xiàn)I/O阻塞的時候,由協(xié)程的調(diào)度器進行調(diào)度
通過將數(shù)據(jù)流立刻yield掉(主動讓出),并記錄當(dāng)前棧上的數(shù)據(jù)
阻塞完成后立刻在通過線程恢復(fù)棧,并把阻塞的結(jié)果放到這個線程上去跑
而跑在由Coroutine
負(fù)責(zé)調(diào)度的線程稱為Fiber
,比如Golang里的go
關(guān)鍵字其實就是負(fù)責(zé)開啟一個Fiber
,讓func
邏輯跑在上面。
由于協(xié)程的暫停完全由程序控制,發(fā)生在用戶態(tài)上;而線程的阻塞狀態(tài)是由操作系統(tǒng)內(nèi)核來進行切換,發(fā)生在內(nèi)核態(tài)上。
因此協(xié)程的開銷遠遠小于線程,也就沒有上下文切換的開銷。
比較項 | 線程 | 協(xié)程 |
---|---|---|
占用資源 | 初始單位為1MB,固定不可變 | 初始一般為2KB,可隨需要增大 |
調(diào)度所屬 | 有OS內(nèi)核完成 | 由用戶完成 |
切換開銷 | 設(shè)計模式切換(從用戶態(tài)切換到內(nèi)核態(tài)),16個寄存器、PC、SP等寄存器的刷新 | 只有三個寄存器的值修改:PC、SP、DX |
性能問題 | 資源占用太高,頻繁創(chuàng)建銷毀會帶來嚴(yán)重的性能問題 | 資源占用小,不會帶來嚴(yán)重的性能問題 |
數(shù)據(jù)同步 | 需要鎖等機制確保數(shù)據(jù)的一致性和可見性 | 不需要多線程的鎖機制,因此只有一個線程。也不存在同時寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比線程高很多 |
到此,關(guān)于“go語言中線程和進程的區(qū)別有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。