首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以启动多线程处理网络IO吗?

可以启动多线程处理网络IO吗?
EN

Stack Overflow用户
提问于 2015-09-03 16:10:56
回答 1查看 4.3K关注 0票数 2

我想用GoLang开发一个软件来处理来自多个tcp连接的请求,并使用10 GoLang在服务器上运行。

似乎这种性能不足以在单个核上重新/发送数据。因此,我想要实现的软件,以重新/发送数据在多个cpu核心。

然后,我制作了一个简单的测试服务器,以检查GoLang是否可以在多个cpu核上恢复/发送数据。它启动多个(16) goroutines,在同一个侦听器上启动http服务器,并使用ab(Apache基准)作为客户端。

服务器启动后,我只看到一个线程调用EpollWait,但是服务器启动了18个线程,当我使用16个并发性启动ab测试时,服务器只占用了一个核心。

因此,问题是:在GoLang中是否有任何方法可以启动多个线程来处理来自多个tcp连接的数据recv/发送。或者我应该调用syscall.EpollWait来创建一个网络框架,然后自己去做呢?

服务器的测试代码:

代码语言:javascript
复制
package main

import (
  "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)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-03 16:22:55

不完全同意。

Go运行时(截止到go1.5)使用单个网络轮询器。当您在服务器中完成实际工作时,这很少是瓶颈,运行goroutines的线程将保持忙碌。但是,在某些情况下,无论是有足够的内核,还是足够的吞吐量,Go运行时都会开始受到影响,特别是因为轮询器通常位于与执行IO的线程不同的NUMA节点中。

如果您需要在这种规模上运行,我建议将Go服务器限制为单个NUMA节点,并运行服务器的多个实例。

这方面的例外是,如果将套接字置于阻塞模式,则该套接字上的IO将绑定到单个OS线程。我还没有对该方法进行任何吞吐量测试,以确定是否有任何好处,但如果同时使用的套接字相对较少,那么尝试也不会有什么害处。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32380653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档