個人覺得golang十分適合進行網游服務器端開發,寫下這篇文章總結一下。 從網游的角度看: 要成功的運營一款網游,很大程度上依賴于玩家自發形成的社區。只有玩家自發形成一個穩定的生態系統,游戲才能持續下去,避免鬼城的出現。而這就需要多次大量導入用戶,在同時在線用戶量達到某個臨界點的時候,才有可能完成。因此,多人同時在線十分有必要。 再來看網游的常見玩法,除了排行榜這類統計和數據匯總的功能外,基本沒有需要大量CPU時間的應用。以前的項目里,即時戰斗產生的各種傷害計算對CPU的消耗也不大。玩家要完成一次操作,需要通過客戶端-服務器端-客戶端這樣一個來回,為了獲得高響應速度,滿足玩家體驗,服務器端的處理也不能占用太多時間。所以,每次請求對應的CPU占用是比較小的。 網游的IO主要分兩個方面,一個是網絡IO,一個是磁盤IO。網絡IO方面,可以分成美術資源的IO和游戲邏輯指令的IO,這里主要分析游戲邏輯的IO。游戲邏輯的IO跟CPU占用的情況相似,每次請求的字節數很小,但由于多人同時在線,因此并發數相當高。另外,地圖信息的廣播也會帶來比較頻繁的網絡通信。磁盤IO方面,主要是游戲數據的保存。采用不同的數據庫,會有比較大的區別。以前的項目里,就經歷了從MySQL轉向MongoDB這種內存數據庫的過程,磁盤IO不再是瓶頸。總體來說,還是用內存做一級緩沖,避免大量小數據塊讀寫的方案。 針對網游的這些特點,golang的語言特性十分適合開發游戲服務器端。 首先,go語言提供goroutine機制作為原生的并發機制。每個goroutine所需的內存很少,實際應用中可以啟動大量的goroutine對并發連接進行響應。goroutine與gevent中的greenlet很相像,遇到IO阻塞的時候,調度器就會自動切換到另一個goroutine執行,保證CPU不會因為IO而發生等待。而goroutine與gevent相比,沒有了python底層的GIL限制,就不需要利用多進程來榨取多核機器的性能了。通過設置最大線程數,可以控制go所啟動的線程,每個線程執行一個goroutine,讓CPU滿負載運行。 同時,go語言為goroutine提供了獨到的通信機制channel。channel發生讀寫的時候,也會掛起當前操作channel的goroutine,是一種同步阻塞通信。這樣既達到了通信的目的,又實現同步,用CSP模型的觀點看,并發模型就是通過一組進程和進程間的事件觸發解決任務的。雖然說,主流的編程語言之間,只要是圖靈完備的,他們就都能實現相同的功能。但go語言提供的這種協程間通信機制,十分優雅地揭示了協程通信的本質,避免了以往鎖的顯式使用帶給程序員的心理負擔,確是一大優勢。進行網游開發的程序員,可以將游戲邏輯按照單線程阻塞式的寫,不需要額外考慮線程調度的問題,以及線程間數據依賴的問題。因為,線程間的channel通信,已經表達了線程間的數據依賴關系了,而go的調度器會給予妥善的處理。 另外,go語言提供的gc機制,以及對指針的保護式使用,可以大大減輕程序員的開發壓力,提高開發效率。 展望未來,我期待go語言社區能夠提供更多的goroutine間的隔離機制。個人十分推崇erlang社區的脆崩哲學,推動應用發生預期外行為時,盡早崩潰,再fork出新進程處理新的請求。對于協程機制,需要由程序員保證執行的函數不會發生死循環,導致線程卡死。

10年的克拉瑪依網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。營銷型網站建設的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整克拉瑪依建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“克拉瑪依網站設計”,“克拉瑪依網站推廣”以來,每個客戶項目都認真落實執行。
Go的CSP并發模型
Go實現了兩種并發形式。第一種是大家普遍認知的:多線程共享內存。其實就是Java或者C++等語言中的多線程開發。另外一種是Go語言特有的,也是Go語言推薦的:CSP(communicating sequential processes)并發模型。
CSP 是 Communicating Sequential Process 的簡稱,中文可以叫做通信順序進程,是一種并發編程模型,由 Tony Hoare 于 1977 年提出。簡單來說,CSP 模型由并發執行的實體(線程或者進程)所組成,實體之間通過發送消息進行通信,這里發送消息時使用的就是通道,或者叫 channel。CSP 模型的關鍵是關注 channel,而不關注發送消息的實體。 Go 語言實現了 CSP 部分理論 。
“ 不要以共享內存的方式來通信,相反, 要通過通信來共享內存。”
Go的CSP并發模型,是通過 goroutine和channel 來實現的。
goroutine 是Go語言中并發的執行單位。其實就是協程。
channel是Go語言中各個并發結構體(goroutine)之前的通信機制。 通俗的講,就是各個goroutine之間通信的”管道“,有點類似于Linux中的管道。
Channel
Goroutine
參考:
Goroutine并發調度模型深度解析手擼一個協程池
Golang 的 goroutine 是如何實現的?
Golang - 調度剖析【第二部分】
OS線程初始棧為2MB。Go語言中,每個goroutine采用動態擴容方式,初始2KB,按需增長,最大1G。此外GC會收縮棧空間。
BTW,增長擴容都是有代價的,需要copy數據到新的stack,所以初始2KB可能有些性能問題。
更多關于stack的內容,可以參見大佬的文章。 聊一聊goroutine stack
用戶線程的調度以及生命周期管理都是用戶層面,Go語言自己實現的,不借助OS系統調用,減少系統資源消耗。
Go語言采用兩級線程模型,即用戶線程與內核線程KSE(kernel scheduling entity)是M:N的。最終goroutine還是會交給OS線程執行,但是需要一個中介,提供上下文。這就是G-M-P模型
Go調度器有兩個不同的運行隊列:
go1.10\src\runtime\runtime2.go
Go調度器根據事件進行上下文切換。
調度的目的就是防止M堵塞,空閑,系統進程切換。
詳見 Golang - 調度剖析【第二部分】
Linux可以通過epoll實現網絡調用,統稱網絡輪詢器N(Net Poller)。
文件IO操作
上面都是防止M堵塞,任務竊取是防止M空閑
每個M都有一個特殊的G,g0。用于執行調度,gc,棧管理等任務,所以g0的棧稱為調度棧。g0的棧不會自動增長,不會被gc,來自os線程的棧。
go1.10\src\runtime\proc.go
G沒辦法自己運行,必須通過M運行
M通過通過調度,執行G
從M掛載P的runq中找到G,執行G
當前題目:go語言并發與線程通信 go語言 并發
文章位置:http://www.yijiale78.com/article4/doddhie.html
成都網站建設公司_創新互聯,為您提供營銷型網站建設、動態網站、網站策劃、靜態網站、Google、企業網站制作
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯