2014-09-28 36 views
1

如何利用所有的CPU併爲每個CPU產生一個http進程? CPU的如何通過http使用多個進程

獲取NUM

numCPU := runtime.NumCPU() 

開始HTTP

package main 

import (
    "fmt" 
    "net/http" 
) 

func handler(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) 
} 

func main() { 
    http.HandleFunc("/", handler) 
    http.ListenAndServe(":8080", nil) 
} 

回答

5

如果你的目標只是讓你的請求處理代碼上的所有CPU核上運行,net/http已經開始goroutine每個連接(一個模糊的線索,像圍棋,具體實施的事情)。您只需在程序開始時使用runtime.GOMAXPROCS(runtime.NumCPU())以允許goroutine在多個核心上運行。

Accept循環在單個goroutine中運行,但解析請求和生成響應的實際工作在每個連接中運行一次。

此行數量將是錯誤的未來該怎麼走的版本,但現在你可以看到實際的go聲明丟給夠程在http://golang.org/src/pkg/net/http/server.go#L1721

+0

在node.js的大多是多連接和其他一些實現(進程不是多線程的),接受在多個「進程」/「線程」上運行。我認爲這就是他的意思,但我可以完全離開這裏。 – OneOfOne 2014-09-28 18:32:24

+0

只是澄清說,只有請求處理在goroutines(當我看到您的評論時正在寫入該添加!)。老實說不確定他們想要什麼,所以留給他們看。 – twotwotwo 2014-09-28 18:36:29

+0

在nodejs中,你必須使用'cluster'爲每個CPU產生一個新的線程。但是在Go中你只需要設置'runtime.GOMAXPROCS(runtime.NumCPU())'來實現相同的目標呢?這是否正確:) – clarkk 2014-09-28 19:19:55

1

你不能nativly,你必須寫自己的包裝:

// copied from http://golang.org/src/pkg/net/http/server.go#L1942 
type tcpKeepAliveListener struct { 
    *net.TCPListener 
} 

func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { 
    tc, err := ln.AcceptTCP() 
    if err != nil { 
     return 
    } 
    tc.SetKeepAlive(true) 
    tc.SetKeepAlivePeriod(3 * time.Minute) 
    return tc, nil 
} 

func ListenAndServe(addr string, num int) error { 
    if addr == "" { 
     addr = ":http" 
    } 
    ln, err := net.Listen("tcp", addr) 
    if err != nil { 
     return err 
    } 
    var wg sync.WaitGroup 
    for i := 0; i < num; i++ { 
     wg.Add(1) 
     go func(i int) { 
      log.Println("listener number", i) 
      log.Println(http.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}, nil)) 

      wg.Done() 
     }(i) 
    } 
    wg.Wait() 
    return nil 
} 

func main() { 
    num := runtime.NumCPU() 
    runtime.GOMAXPROCS(num) //so the goroutine listeners would try to run on multiple threads 
    log.Println(ListenAndServe(":9020", num)) 
} 

或者,如果您使用的是最近有足夠的Linux Kernel,你可以使用來自http://comments.gmane.org/gmane.comp.lang.go.general/121122的補丁,並且實際上產生多個進程。