1

奇怪的是,在我的情况下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()
  }

功能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)
  }
}

问题是,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)))意思。

4

1 回答 1

8

您没有正确处理 TCP。当 conn.Read() 返回读取的 0 字节时,这意味着对等方已经优雅地关闭了 TCP 连接。在这种情况下,您可能应该关闭 TCP 连接的一端。

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

于 2013-05-13T07:40:50.487 回答