2014-08-28 50 views
0
package main 
import "fmt" 
import "time" 

func main() { 
    message := make(chan string ,1) // no buffer 
    count := 3 

    go func() { 
      for i := 1; i <= count; i++ { 
       fmt.Println("send message") 
       message <- fmt.Sprintf("message %d", i) 
      } 
    }() 

    time.Sleep(time.Second * 3) 

    for i := 1; i <= count; i++ { 
      fmt.Println(<-message) 
    } 
} 

輸出是去信道容量,爲什麼它比我指定需要多一個元素

send message 
send message [wait for 3 sec] 
message 1 
send message 
message 2 
message 3 

如果我改變message := make(chan string ,1) // no buffer

message := make(chan string ,2) // no buffer 

send message 
send message 
send message [wait 3 sec] 
message 1 
message 2 
message 3 

爲什麼2緩衝區chann el可以存儲3個字符串對象嗎?不是2?

感謝,

回答

2

它的工作原理是這樣的,因爲它緩衝塊之前持有N個消息。當N + 1消息進入GO時,會看到它超出了您指定的容量,並且將不得不阻止,等待從該通道獲取的內容。當傳遞緩衝區大小時,發送方將始終阻塞N + 1個消息。

因此,例如大小爲2,你有一個空的緩衝區:

[] []

然後消息傳入,被放入緩衝區:

[M1] []

然後再一個,我們可以繼續走下去,因爲我們在緩衝區中有空間

[M1] [2]

然後又進來,跌宕我們沒有在緩衝區更多的空間,所以我們阻止

[M1] [2]立方米 - >阻止

這樣的事情。

大小基本上是可以發送到緩衝區而沒有阻塞的消息的數量。

對於未來我建議http://golang.org/doc/effective_go.html#channels

var sem = make(chan int, MaxOutstanding) 

一旦MaxOutstanding處理程序執行過程中,任何更多的將 塊試圖發送到填充通道緩衝器,直到 現有處理程序完成的一個,並接收來自緩衝區。