Go package syscall conn.Read()是非阻塞的并导致高CPU使用率

Rec*_*Hou 1 networking network-programming tcp system-calls go

奇怪的是,在我的情况下Read()是非阻塞并导致高CPU使用率.

我的代码:

功能main:

l, err := net.Listen("tcp", ":13798")


if err != nil {
    log.Fatal(err)
  }

  for {
    // Wait for a connection.
    conn, err := l.Accept()
    if err != nil {
      log.Fatal(err)
    }
    // Handle the connection in a new goroutine.
    // The loop then returns to accepting, so that
    // multiple connections may be served concurrently.
    go reqHandler.TCPHandler(conn)

    runtime.Gosched()
  }
Run Code Online (Sandbox Code Playgroud)

功能TCPHandler:

func TCPHandler(conn net.Conn) {
request := make([]byte, 4096)
  for {
    read_len, err := conn.Read(request)

    if err != nil {
        if err.Error() == "use of closed network connection" {
        LOG("Conn closed, error might happened")
        break
      }

      neterr, ok := err.(net.Error);
      if ok && neterr.Timeout() {
        fmt.Println(neterr)
        LOG("Client timeout!")
        break
      }
    }

    if read_len == 0 {
     LOG("Nothing read")
      continue
    } else {
      // do something
    }
    request := make([]byte, 4096)
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是,conn.Read()是非阻塞的,所以每次进行LOG("Nothing read")然后继续,这都会导致高CPU使用率.如何conn.Read()拨打电话?

我已经研究过syscall包但是一直坚持Syscall.Read() 因为我在OS X 10.8.3上发现了这个问题,这里是相关的源代码:

http://golang.org/src/pkg/syscall/zsyscall_darwin_amd64.go?h=Read#L898

我不知道是什么Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))意思.

nos*_*nos 8

您没有正确处理TCP.当conn.Read()返回0字节读取时,这意味着对等体已正常关闭TCP连接.在这种情况下,您应该关闭TCP连接的末尾.

(注意,这对Go来说并不特殊,read()/ recv()在TCP连接上返回0或多或少普遍意味着另一端已关闭连接)