2013-05-13 54 views
1

奇怪的是,在我的情況下,Read()是非阻塞的並且導致高CPU使用率。Go package syscall conn.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() 得到stucked因爲我發現這個問題上我的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)))的意思。

+3

這是一個壞主意:'如果err.Error()==「使用封閉的網絡連接」# – thwd 2013-05-13 11:49:26

回答

8

你沒有正確處理TCP。當conn.Read()返回0字節時,表示對等體已經正常關閉了TCP連接。在這種情況下,您應該關閉TCP連接的結束。

(請注意,這不是特別去,閱讀()/ recv的()一個TCP連接上返回0,或多或少普遍指另一端已經關閉了連接)

+1

呃......你說得對,把'continue'改成'break'運行良好 – 2013-05-13 07:43:52

相關問題