亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

golang可以啟動多線程來處理網絡IO嗎

golang可以啟動多線程來處理網絡IO嗎

Go
呼啦一陣風 2021-11-01 17:37:01
我想開發一個軟件來使用 GoLang 處理來自多個 tcp 連接的請求,并在具有 10Gb-nic 的服務器上運行??磥硇阅懿粔騿魏藃ecv/send數據。所以我想實現該軟件以在多個 cpu 內核上接收/發送數據。然后我做了一個簡單的測試服務器來檢查 GoLang 是否可以在多個 cpu 內核上接收/發送數據。它啟動多個 (16) goroutines 在同一個監聽器上啟動 http 服務器,并使用 ab(Apache Benchmark) 作為客戶端。服務器啟動后,我看到只有一個線程調用了EpollWait,但是服務器啟動了18個線程,而當我啟動ab測試時使用了16個并發,但服務器只占用一個核心。所以問題是:有沒有辦法啟動多個線程來處理來自 GoLang 中多個 tcp 連接的數據接收/發送。或者我應該調用 syscall.EpollWait 來制作一個網絡框架,自己做嗎?服務器的測試代碼:package mainimport (  "io"  "log"  "net"  "net/http"  "runtime")type HandlerFunction struct{}func (self HandlerFunction) ServeHTTP(w http.ResponseWriter, req *http.Request) {  data := "Hello"  //fmt.Printf("data_len=%d\n", len(data))  io.WriteString(w, string(data))}func RoutineFunction(hs *http.Server, l net.Listener) {  runtime.LockOSThread()  err := hs.Serve(l)  if err != nil {    log.Fatalf("serve fail, err=[%s]", err)  }}func main() {  runtime.GOMAXPROCS(16)  l, err := net.Listen("tcp", "0.0.0.0:12345")  if err != nil {    log.Fatalf("listen fail, err=[%s]", err)  }  for i := 0; i < 15; i++ {    hs := http.Server{}    hs.Handler = HandlerFunction{}    go RoutineFunction(&hs, l)  }  hs := http.Server{}  hs.Handler = HandlerFunction{}  RoutineFunction(&hs, l)}
查看完整描述

1 回答

?
陪伴而非守候

TA貢獻1757條經驗 獲得超8個贊

不完全是。

Go 運行時(從 go1.5 開始)使用單個網絡輪詢器。當您在服務器中完成實際工作時,這很少是瓶頸,并且運行 goroutines 的線程將保持忙碌。但在某些情況下,無論是擁有足夠的內核還是足夠的吞吐量,Go 運行時都會開始受到影響,特別是因為輪詢器通常位于與執行 IO 的線程不同的 NUMA 節點中。

如果您需要以這種規模運行,我目前建議將 Go 服務器限制為單個 NUMA 節點,并運行該服務器的多個實例。

例外情況是,如果您將套接字置于阻塞模式,則該套接字上的 IO 將綁定到單個 OS 線程。我還沒有對這種方法進行任何吞吐量測試以查看是否有任何好處,但是如果您同時使用相對較少的套接字,那么嘗試一下也無妨。


查看完整回答
反對 回復 2021-11-01
  • 1 回答
  • 0 關注
  • 369 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號