摘要:協(xié)程完全有用戶態(tài)程序控制,所以也被成為用戶態(tài)的線程。目前支持協(xié)程的語言有很多,例如等。協(xié)程之旅前篇結(jié)束,下一篇文章我們將深入分析原生協(xié)程部分的實(shí)現(xiàn)。
寫在最前
??Swoole協(xié)程經(jīng)歷了幾個(gè)里程碑,我們需要在前進(jìn)的道路上不斷總結(jié)與回顧自己的發(fā)展歷程,正所謂溫故而知新,本系列文章將分為協(xié)程之旅前、中、后三篇。
前篇主要介紹協(xié)程的概念和Swoole幾個(gè)版本協(xié)程實(shí)現(xiàn)的主要方案技術(shù);
中篇主要深入Zend分析PHP部分的原理和實(shí)現(xiàn);
后篇主要補(bǔ)充和分析協(xié)程4.x的實(shí)現(xiàn)。
軟文正式開始 協(xié)程是什么???概念其實(shí)很早就出現(xiàn)了,摘wiki一段:According to Donald Knuth, the term coroutine was coined by Melvin Conway in 1958, after he applied it to construction of an assembly program.The first published explanation of the coroutine appeared later, in 1963. 協(xié)程要比c語言的歷史還要悠久,究其概念,協(xié)程是子程序的一種, 可以通過yield的方式轉(zhuǎn)移程序控制權(quán),協(xié)程之間不是調(diào)用者與被調(diào)用者的關(guān)系,而是彼此對(duì)稱、平等的。協(xié)程完全有用戶態(tài)程序控制,所以也被成為用戶態(tài)的線程。協(xié)程由用戶以非搶占的方式調(diào)度,而不是操作系統(tǒng)。正因?yàn)槿绱?,沒有系統(tǒng)調(diào)度上下文切換的開銷,協(xié)程有了輕量,高效,快速等特點(diǎn)。(大部分為非搶占式,但是,比如golang在1.4也加入了搶占式調(diào)度,其中一個(gè)協(xié)程發(fā)生死循環(huán),不至于其他協(xié)程被餓死。需要在必要的時(shí)刻讓出CPU,Swoole在V4.3.2增加了這個(gè)特性)。
??協(xié)程近幾年如此火爆,很大一部分原因歸功與golang在中國(guó)的流行和快速發(fā)展,受到很多開發(fā)的喜愛。目前支持協(xié)程的語言有很多,例如: golang、lua、python、c#、javascript等。大家也可以用很短的代碼用c/c++擼出協(xié)程的模型。當(dāng)然PHP也有自己的協(xié)程實(shí)現(xiàn),也就是生成器,我們這里不展開討論。
Swoole1.x?? Swoole最初以高性能網(wǎng)絡(luò)通訊引擎的姿態(tài)進(jìn)入大家視線,Swoole1.x的編碼主要是異步回調(diào)的方式,雖然性能非常高效,但很多開發(fā)都會(huì)發(fā)現(xiàn),隨著項(xiàng)目工程的復(fù)雜程度增加,以異步回調(diào)的方式寫業(yè)務(wù)代碼是和人類正常思維相悖的,尤其是回調(diào)嵌套多層的時(shí)候,不僅開發(fā)維護(hù)成本指數(shù)級(jí)上升,而且出錯(cuò)的幾率也大幅增加。大家理想的編碼方式是:同步編碼得到異步非阻塞的性能。所以Swoole很早的時(shí)候就開始了協(xié)程的探索。
??最初的協(xié)程版本是基于PHP生成器GeneratorsYield的方式實(shí)現(xiàn)的,可以參考PHP大神Nikita的早期博客的關(guān)于協(xié)程介紹。PHP和Swoole的事件驅(qū)動(dòng)的結(jié)合可以參考騰訊出團(tuán)隊(duì)開源的TSF框架,我們也在很多生產(chǎn)項(xiàng)目中使用了該框架,確實(shí)讓大家感受到了,以同步編程的方式寫異步代碼的快感,然而,現(xiàn)實(shí)總是很殘酷,這種方式有幾個(gè)致命的缺點(diǎn):
所有主動(dòng)讓出的邏輯都需要yield關(guān)鍵字。這會(huì)給程序員帶來極大的概率犯錯(cuò),導(dǎo)致大家對(duì)協(xié)程的理解轉(zhuǎn)移到了對(duì)Generators語法的原理的理解。
由于語法無法兼容老的項(xiàng)目,改造老的項(xiàng)目工程復(fù)雜度巨大,成本太高。
這樣使得無論新老項(xiàng)目,使用都無法得心應(yīng)手。
Swoole2.x?? 2.x之后的協(xié)程都是基于內(nèi)核原生的協(xié)程,無需yield關(guān)鍵字。2.0的版本是一個(gè)非常重要的里程碑,實(shí)現(xiàn)了php的棧管理,深入zend內(nèi)核在協(xié)程創(chuàng)建,切換以及結(jié)束的時(shí)候操作PHP棧。在Swoole的文檔中也介紹了很多關(guān)于每個(gè)版本實(shí)現(xiàn)的細(xì)節(jié),我們這篇文章只對(duì)每個(gè)版本的協(xié)程驅(qū)動(dòng)技術(shù)做簡(jiǎn)單介紹。原生協(xié)程都有對(duì)php棧的管理,后續(xù)我們會(huì)多帶帶拿一片文章來深入分析PHP棧的管理和切換。
?? 2.x主要使用了setjmp/longjmp的方式實(shí)現(xiàn)協(xié)程,很多C項(xiàng)目主要采用這種方式實(shí)現(xiàn)try-catch-finally,大家也可以參考Zend內(nèi)核的用法。setjmp的首次調(diào)用返回值是0,longjmp跳轉(zhuǎn)時(shí),setjmp的返回值是傳給longjmp的value。 setjmp/longjmp由于只有控制流跳轉(zhuǎn)的能力。雖然可以還原PC和棧指針,但是無法還原棧幀,因此會(huì)出現(xiàn)很多問題。比如longjmp的時(shí)候,setjmp的作用域已經(jīng)退出,當(dāng)時(shí)的棧幀已經(jīng)銷毀。這時(shí)就會(huì)出現(xiàn)未定義行為。假設(shè)有這樣一個(gè)調(diào)用鏈:
func0() -> func1() -> ... -> funcN()
只有在func{i}()中setjmp,在func{i+k}()中l(wèi)ongjmp的情況下,程序的行為才是可預(yù)期的。
Swoole3.x3.x是生命周期很短的一個(gè)版本,主要借鑒了fiber-ext項(xiàng)目,使用了PHP7的VM interrupts機(jī)制,該機(jī)制可以在vm中設(shè)置標(biāo)記位,在執(zhí)行一些指令的時(shí)候(例如:跳轉(zhuǎn)和函數(shù)調(diào)用等)檢查標(biāo)記位,如果命中就可以執(zhí)行相應(yīng)的hook函數(shù)來切換vm的棧,進(jìn)而實(shí)現(xiàn)協(xié)程。雖然我們完整的實(shí)現(xiàn)了協(xié)程的功能,但是由于并沒有相對(duì)2.x有很大的進(jìn)步,原因我們后續(xù)的文章會(huì)做進(jìn)一步分析,所以我們放棄了這個(gè)版本,直接進(jìn)入了4.x的版本迭代。
Swoole4.x4.x協(xié)程是當(dāng)前Swoole的協(xié)程版本,借鑒了前面版本的缺點(diǎn)和問題,引入了PHP+C雙棧管理維護(hù),完美的支持PHP各種語法,詳細(xì)分析我們放在系列文章最后。
End協(xié)程之旅前篇結(jié)束,下一篇文章我們將深入Zend分析Swoole原生協(xié)程PHP部分的實(shí)現(xiàn)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/31278.html
摘要:在中的應(yīng)用官網(wǎng)源碼解讀號(hào)外號(hào)外歡迎大家我們開發(fā)組定了一個(gè)就線下聚一次的小目標(biāo)上一篇源碼解讀反響還不錯(cuò)不少同學(xué)推薦再加一篇講解一下中使用到的功能幫助大家開啟的實(shí)戰(zhàn)之旅服務(wù)器開發(fā)涉及到的相關(guān)技術(shù)領(lǐng)域的知識(shí)非常多不日積月累打好基礎(chǔ)是很難真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的應(yīng)用 swoft 官網(wǎng): https://www.sw...
摘要:搶占式調(diào)度我們?cè)诮衲昴瓿蹙陀?jì)劃實(shí)現(xiàn)的搶占式調(diào)度,以滿足實(shí)現(xiàn)有些場(chǎng)景下的不均衡調(diào)度帶來的問題。考慮開線程,負(fù)責(zé)檢查當(dāng)前執(zhí)行協(xié)程執(zhí)行時(shí)間。達(dá)到我們的第二個(gè)協(xié)程主動(dòng)搶占第一個(gè)協(xié)程的效果。 前言 Swoole內(nèi)核團(tuán)隊(duì)開設(shè)的專欄,會(huì)逐漸投入精力寫文章介紹Swoole的開發(fā)歷程,實(shí)現(xiàn)原理,應(yīng)用實(shí)踐等,大家可以更好的交流,共同學(xué)習(xí),建設(shè)PHP生態(tài)。 協(xié)程調(diào)度 去年Swoole推出了4.0版本后,完整...
摘要:初識(shí)協(xié)程執(zhí)行結(jié)果協(xié)程與同步模式比較我們一直在說協(xié)程適合用于密集場(chǎng)景,在同樣的硬件配置環(huán)境下,它會(huì)比傳統(tǒng)的同步模式承載更多的訪問量。假設(shè)一次查詢?yōu)?,在傳統(tǒng)同步模式下,當(dāng)前進(jìn)程在這的時(shí)間里,是不能做其它操作的。同步模式,耗費(fèi)左右的是。 如果說數(shù)組是 PHP 的精髓,數(shù)組玩得不6的,根本不能算是會(huì)用PHP。那協(xié)程對(duì)于 Swoole 也是同理,不理解協(xié)程去用 Swoole,那就是在瞎用。 首先...
摘要:之后協(xié)程化支持已經(jīng)完善并且支持大量的擴(kuò)展自動(dòng)協(xié)程化一些基于的框架也蓬勃發(fā)展光看著文檔就讓人躍躍欲試但是對(duì)于現(xiàn)有舊項(xiàng)目如何引入并啟用協(xié)程成了實(shí)際場(chǎng)景中的客觀問題由于協(xié)程性質(zhì)及生命周期等原因這并非想象的那么容易本文整理了在現(xiàn)有項(xiàng)目中引入并開啟協(xié) Swoole4之后,協(xié)程化支持已經(jīng)完善,并且支持大量的PHP擴(kuò)展自動(dòng)協(xié)程化.一些基于Swoole4的框架也蓬勃發(fā)展,光看著文檔就讓人躍躍欲試.但是...
摘要:為語言提供了強(qiáng)大的協(xié)程編程模式。提供的協(xié)程語法借鑒自,在此向開發(fā)組致敬協(xié)程可以與很好地互補(bǔ)。并發(fā)執(zhí)行使用創(chuàng)建協(xié)程,可以讓和兩個(gè)函數(shù)變成并發(fā)執(zhí)行。協(xié)程需要拿到請(qǐng)求的結(jié)果。 Swoole4為PHP語言提供了強(qiáng)大的CSP協(xié)程編程模式。底層提供了3個(gè)關(guān)鍵詞,可以方便地實(shí)現(xiàn)各類功能。 Swoole4提供的PHP協(xié)程語法借鑒自Golang,在此向GO開發(fā)組致敬 PHP+Swoole協(xié)程可以與...
閱讀 2535·2021-11-22 13:53
閱讀 1220·2021-09-22 16:06
閱讀 1461·2021-09-02 15:21
閱讀 2012·2019-08-30 15:55
閱讀 3209·2019-08-29 11:19
閱讀 1990·2019-08-26 13:23
閱讀 1020·2019-08-23 18:23
閱讀 1829·2019-08-23 16:06