如何進(jìn)行l(wèi)ibgo的源碼剖析,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
目前創(chuàng)新互聯(lián)已為1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、東臺(tái)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。閑談協(xié)程是一個(gè)很早的概念了,早些年的游戲行業(yè)中已經(jīng)大規(guī)模地在使用,像lua、go這些語言中的協(xié)程原語已經(jīng)相對比較完善了,一般來說直接使用就好,但是在系統(tǒng)后臺(tái)開發(fā)上,出現(xiàn)的時(shí)間并不長。
我是做C++方向的后臺(tái)開發(fā),目前國內(nèi)一些公司也開源了一些C++協(xié)程庫,但目前來說,還是在逐步完善的階段。最早接觸的C++協(xié)程庫是騰訊微信的 libco,可以說是相當(dāng)輕量級的協(xié)程,網(wǎng)上關(guān)于libco的實(shí)現(xiàn)的文章也是相對較多,這里的話不會(huì)去過多地?cái)⑹觥?/p>
在網(wǎng)上查找關(guān)于 libgo 的資料,關(guān)于代碼實(shí)現(xiàn)的文章并沒有多少,因此,打算自己看代碼總結(jié),之后的文章中,可能會(huì)針libgo和libco的部分功能進(jìn)行簡單對比,不足之處,希望讀者指出。
背景因?yàn)楣ぷ餍枰?,以前系統(tǒng)的異步框架已經(jīng)顯得不再那么地具有擴(kuò)展性,異步使得原本很簡單的邏輯(讀->處理->寫),要拆分開來成多個(gè)階段,通過回調(diào)來響應(yīng)各個(gè)事件,因此有計(jì)劃地使用協(xié)程來代替。
為什么最后選擇了libgo,而沒有選擇更加輕量級的libco ?網(wǎng)上有人給出過兩者的性能對比,從自旋鎖、協(xié)程的數(shù)量以及??臻g、線程支持等各個(gè)角度考慮,貌似libgo完勝。
協(xié)程圖片來源于網(wǎng)絡(luò)
性能對比數(shù)據(jù)來源于網(wǎng)絡(luò),并不是說libco不好,也許各自應(yīng)用的場景略有不同,libco幾千行的代碼可以實(shí)現(xiàn)一個(gè)相對較完備的協(xié)程,而且經(jīng)得住微信后臺(tái)龐大的數(shù)據(jù)流量,自有它的優(yōu)勢。由于對 libgo 的代碼正在研究當(dāng)中,因此,暫不對兩者評價(jià)。
不管是什么樣的協(xié)程,最核心的內(nèi)容,都是在系統(tǒng)發(fā)生阻塞的時(shí)候上層主動(dòng)讓出CPU,切換就緒協(xié)程的上下文,簡要總結(jié),有如下幾個(gè)方面:
上下文切換的實(shí)現(xiàn)
系統(tǒng)函數(shù)的hook;
協(xié)程調(diào)度;
時(shí)間管理;
libgo 目錄結(jié)構(gòu)說明https://github.com/yyzybb537/libgo
muhui@ASIAYANG-MB0:~/code/libgo/libgo-master$ ll total 64 -rw-r--r--@ 1 muhui staff 5913 11 7 11:20 CMakeLists.txt -rw-r--r--@ 1 muhui staff 1084 11 7 11:20 LICENSE -rw-r--r--@ 1 muhui staff 8758 11 7 11:20 README.md -rw-r--r--@ 1 muhui staff 4230 11 7 11:20 TODO drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 imgs drwxr-xr-x@ 15 muhui staff 480 11 7 11:20 libgo drwxr-xr-x@ 8 muhui staff 256 11 7 11:20 test drwxr-xr-x@ 6 muhui staff 192 11 7 11:20 third_party drwxr-xr-x@ 20 muhui staff 640 11 7 11:20 tutorial drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 vs_proj muhui@ASIAYANG-MB0:~/code/libgo/libgo-master$ cd libgo/ muhui@ASIAYANG-MB0:~/code/libgo/libgo-master/libgo$ ll total 16 drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 cls drwxr-xr-x@ 19 muhui staff 608 11 7 11:20 common drwxr-xr-x@ 6 muhui staff 192 11 7 11:20 context -rw-r--r--@ 1 muhui staff 1848 11 7 11:20 coroutine.h drwxr-xr-x@ 5 muhui staff 160 11 7 11:20 debug drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 defer -rw-r--r--@ 1 muhui staff 36 11 7 11:20 libgo.h drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 netio drwxr-xr-x@ 5 muhui staff 160 11 7 11:20 pool drwxr-xr-x@ 8 muhui staff 256 11 7 11:20 scheduler drwxr-xr-x@ 7 muhui staff 224 11 7 11:20 sync drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 task drwxr-xr-x@ 4 muhui staff 128 11 7 11:20 timer
libgo 做的較好的一點(diǎn)是增加了對windows 環(huán)境的支持等,我們只針對 Linux 環(huán)境做研究。
TODO:libgo 后續(xù)會(huì)逐步完善或增加的功能;
libgo:源碼實(shí)現(xiàn)的主目錄,關(guān)于協(xié)程和調(diào)度策略的實(shí)現(xiàn)都在該目錄下;
test:測試代碼;
tutorial:libgo 使用教程代碼;
vs_proj:VS 環(huán)境下如何使用libgo。
在libgo目錄下
task:協(xié)程的相關(guān)實(shí)現(xiàn);
scheduler:協(xié)程調(diào)度的實(shí)現(xiàn);
debug:libgo 自帶的調(diào)試功能(用于協(xié)程狀態(tài)的定位等);
coroutine.h:對一些常用對方法進(jìn)行了重定義。
netio:hook的系統(tǒng)調(diào)用;
context:上下文的切換;
pool:libgo 實(shí)現(xiàn)的連接池
我們知道,協(xié)程是用戶態(tài)線程,因此libco的話是不支持線程的。但在libgo中,線程同樣是支持的,這于它的調(diào)度方式有關(guān)。
首先我們要說的一點(diǎn)是,在libgo中,每個(gè)協(xié)程是一個(gè)task,libgo 的調(diào)度并不是直接作用于協(xié)程,是通過間接調(diào)度實(shí)現(xiàn)的。
libgo中有調(diào)度器(scheduler)和執(zhí)行器(processer)的概念:
直接負(fù)責(zé)協(xié)程調(diào)度的是執(zhí)行器,它會(huì)在協(xié)程阻塞的時(shí)候切出上下文,并切入一個(gè)就緒協(xié)程的上下文去繼續(xù)處理,當(dāng)沒有可執(zhí)行的協(xié)程時(shí),執(zhí)行器就會(huì)阻塞等待,當(dāng)有新到來的任務(wù)時(shí),會(huì)繼續(xù)處理;
負(fù)責(zé)管理執(zhí)行器的是調(diào)度器,對調(diào)度器而言,每個(gè)執(zhí)行器是一個(gè)單獨(dú)的線程,調(diào)度器做的最主要的工作,就是平衡各個(gè)執(zhí)行器中的協(xié)程數(shù)量,防止饑餓效應(yīng),部分執(zhí)行器過忙,部分執(zhí)行器卻沒有task可執(zhí)行,另外,如果某個(gè)執(zhí)行器卡住,調(diào)度器也會(huì)將執(zhí)行器中的可運(yùn)行協(xié)程取出,放到負(fù)載最低的執(zhí)行器上。
當(dāng)然,調(diào)度器的個(gè)數(shù)的話是支持動(dòng)態(tài)擴(kuò)展的。
如下圖:
看完上述內(nèi)容,你們掌握如何進(jìn)行l(wèi)ibgo的源碼剖析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道,感謝各位的閱讀!