所有的代碼就是?線程來執(zhí)?的土至,?如有?段線程執(zhí)?的時間?谈飒,有起點 A 和終點 B,執(zhí)??段 Logic ?戶代碼肪凛,執(zhí)?到某點時需要做系統(tǒng)調(diào)?堰汉,做系統(tǒng)調(diào)?的時候就會在這?點阻塞辽社,然后執(zhí)?序就進?系統(tǒng)內(nèi)核狀態(tài),?戶線程就會在這地? Block翘鸭,剩下來的時間?就交給系統(tǒng)內(nèi)核去執(zhí)?了滴铅。
假如?戶線程被阻塞住的時候,系統(tǒng)調(diào)?不使?剩下來的時間?就乓,?把系統(tǒng)調(diào)?變成操作系統(tǒng)內(nèi)核的異步調(diào)?汉匙,那么它所使?的時間?實際上是操作系統(tǒng)內(nèi)部的?些時間?,后??段?戶線程的時間?就被空出來了生蚁,空出來的話阻塞那這個時間???浪費掉了噩翠,為什么??浪費掉了?第?種可能就是看使?什么樣的阻塞?式邦投,?種?式阻塞在那?直等?直等什么都不干伤锚,另外?種操作系統(tǒng)覺得剩下來時間?拿?交給別的程序或者線程去執(zhí)?,對于我們進程執(zhí)?來說這很顯然就是性能損失志衣。
所以能不能有這樣的?種模式屯援,當(dāng)程序執(zhí)?線程A執(zhí)?到?點的時候被阻塞了,然后發(fā)??次系統(tǒng)調(diào)?蠢涝,讓
這個系統(tǒng)調(diào)?異步執(zhí)?玄呛,剩下來的時間?不打算交回去,完成?次調(diào)度把這段時間?交給線程B執(zhí)?和二,當(dāng)系
統(tǒng)調(diào)?完成的時候有很多機制實現(xiàn)喚醒,?如說select耳胎、epoll這樣的?些機制惯吕,喚醒把結(jié)果返還給A。這樣的話可以在同?個線程執(zhí)?并發(fā)多個任務(wù)怕午,這些并發(fā)任務(wù)實際上是在?戶態(tài)完成的和操作系統(tǒng)?關(guān)
概念
利?異步機制利???在?戶態(tài)實現(xiàn)這種調(diào)度機制把阻塞的那段時間搶回來?來執(zhí)?其他的任務(wù)废登,當(dāng) B 任務(wù)執(zhí)?結(jié)束的時候下次再執(zhí)?的時候去會檢查epoll返回的事件,然后把A的結(jié)果返還給A郁惜,這樣?來我們在?戶空間實現(xiàn)多任務(wù)的調(diào)度?多任務(wù)調(diào)度是發(fā)?在?個線程上的堡距,我們把這種機制稱之為協(xié)程.
因為操作系統(tǒng)調(diào)度以系統(tǒng)線程為單位的,但是我們在操作系統(tǒng)以外?戶空間再實現(xiàn)?次調(diào)度兆蕉,它每次浪費的時間?都撿回來盡可能去執(zhí)?我們的代碼羽戒,我們可以把這種機制稱之為協(xié)程,就是它?線程粒度更?虎韵,因為它實際在線程上把線程的時間?劃分成多個塊在線程上再去執(zhí)?多個任務(wù)易稠,但是協(xié)程很顯然是串?的它不是真正意義上的并?,實際上是執(zhí)?A任務(wù)當(dāng)A任務(wù)阻塞的時候然后喚醒B任務(wù)包蓝,B任務(wù)完了以后可能做?次檢查看 A 的結(jié)果回沒回來驶社,很顯然它這種切換來實現(xiàn)多任務(wù)并發(fā)企量,協(xié)程本質(zhì)是串?的
原理
他和線程的原理是一樣的,當(dāng)a線程切換到b線程的時候亡电,需要將a線程的相關(guān)執(zhí)行進度壓入棧届巩,然后將b線程的執(zhí)行進度出棧,進入b的執(zhí)行序列份乒。協(xié)程只不過是在應(yīng)用成實現(xiàn)這一點姆泻。
協(xié)程是基于線程的。內(nèi)部實現(xiàn)上冒嫡,維護了一組數(shù)據(jù)結(jié)構(gòu)和n個線程拇勃,真正的執(zhí)行還是線程,協(xié)程執(zhí)行的代碼被扔進一個待執(zhí)行隊列中孝凌,有這n個線程從隊列中拉出來執(zhí)行方咆。這就解決了協(xié)程的執(zhí)行問題。那么協(xié)程是怎么切換的呢蟀架?答案是:golang對各種io函數(shù)進行了封裝瓣赂,這些封裝的函數(shù)提供給應(yīng)用程序使用,而其內(nèi)部調(diào)用了操作系統(tǒng)的異步io函數(shù)片拍,當(dāng)這些異步函數(shù)返回busy或bloking時煌集,golang利用這個時機將現(xiàn)有的執(zhí)行序列壓棧,讓線程去拉另外一個協(xié)程的代碼來執(zhí)行捌省,基本原理就是這樣苫纤,利用并封裝了操作系統(tǒng)的異步函數(shù)。包括linux的epoll纲缓,select和windows的iocp,event等卷拘。