日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go游戏服务器开发的一些思考(十):goroutine和coroutine

發布時間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go游戏服务器开发的一些思考(十):goroutine和coroutine 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概要

go語言的特色之一就是goroutine。也就是go協程。由于協程這個東西在go語言之前,用到相對比較少,大家對協程的理解程度不一,或有偏差。比如本人剛接觸goroutine時,就對其比較畏懼,因為不知道它到底是如何運作的。因此有必要深入了解下什么是協程,它的今生前世,以及工作原理

前世

作為服務器端程序員,一般來說,都會使用過、或者自己實現過 “通用的異步任務系統” ,來達成安全方便的多線程使用。通常來講,比較典型的會是基于actor模型及回調的方式制定差異。

這里我們主要來考察下其不足之處。下面簡單的畫一下 任務對象和線程間的關系:

------- ------- -------| task1 | | task2 | .... | taskn | => thread1------- ------- -------------- ------- -------| taska | | taskb | .... | taskz | => thread2------- ------- -------...------- ------- -------| taskA | | taskB | .... | taskZ | => threadn------- ------- -------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

如圖所示,一般會開n個線程來處理,每個任務按一定的策略被投遞到線程中執行,任務完成后,觸發異步回調。

假設 任務中,有一定比例的任務是IO阻礙的。那么線程在執行這個任務時,會被掛起。導致后面的任務也只能等待。

總結下其不足的地方:

* CPU能力不能達到完全釋放* IO阻塞任務的數量與線程被系統調度成正比* 任務完成需要回調方式,編程上不直觀、比較難受(若沒有前兩條不足,這個大概也不會出現。背鍋俠是也...)

(ps. 協程起源于單CPU單線程時代。要解決的問題,同這里表述的。多線程后,為了榨干CPU處理能力,協程開始用于多線程系統,如這里描述的)

程序員的智慧

那么如何才能把 “異步任務系統” 做的完美呢。假設能這樣就好了:

* IO阻塞任務,執行到阻塞語句時,系統可以下達它的IO指令又可以把它拎出來,重新插到任務隊列最后。

假設能實現這樣的效果。那么上述的不足也就不存在了:

* 阻塞的任務因為拎出來了,后續的任務可以繼續歡快的在該線程上跑了 * 阻塞的任務因為拎出來了,線程也不會被阻塞,也就不會被系統調度出去了

那么如何才能做到。聰明的程序員很快找到了解決方案:
* 將IO阻塞的API hook掉,換成異步實現
* 模仿操作系統線程的調度方法,實現任務的切出切進

這里點下,為什么需要 “實現任務的切出切進”。由于把IO阻塞的API hook掉,換成異步實現。如果讓該任務繼續執行的話,就會改變該任務的流程。因此必須切出去。等再次切進來時,檢查IO事件是否已經到了。到了則如同 IO阻塞完畢,繼續執行任務流程。否則再次切出。

今生

于是很多產品出來了。

首先是操作系統,推出了用戶態 上下文切換API

操作系統API
window纖程(Fiber系列API)
linuxucontext系列API
其他大廠直接自己匯編搞定,高級定制(比如go …)

然后 很多開源庫。這里介紹幾個有名的

開源庫介紹
boostboost::context、boost::coroutine。僅跨平臺提供協程基礎功能。
libco騰訊的協程庫。明顯的閹割版放出。沒有提供上層封裝使用層代碼
libgo魅族的協程庫。和goroutine使用功能上無限接近。
libtaskgoroutine前身。goroutine一出,大家驚呆了,原來封裝的好,也可以這么好用。

順便吐槽下,翻下libco、libgo、libtask,會發現代碼中只有task。而到了市面上則變成了 協程(coroutine)。玩起概念來…

goroutine、libgo、libco 比較

開源庫HOOK情況協程大小功能完成度(goroutine用法為參照)代碼可讀性
goroutine全部hook8K開始,動態增加,分段棧實現100%go代碼太龐大,還沒找到…
libcosocket系列API可制定大小,共享棧實現最基本的協程功能代碼量小,比較難看,沒看
libgosocket系列API可制定大小,沒有特殊實現接近100%代碼量小,可讀性很高,基本看懂

(ps.據libgo的作者說,libgo協程棧用了 “os的虛擬內存機制,是動態增長的”。待考究優略 )

C++框架新的可能

C++ libgo庫設計的非常棒,還原 goroutine 程度 接近100%(當然這里指的是用法。穩定性、可靠性還需很多人、產品的檢驗)。因此讓C++引擎具備實用的cocoutine系統已經是完全可行。

總結

以上是生活随笔為你收集整理的Go游戏服务器开发的一些思考(十):goroutine和coroutine的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。