nilチャネルから要素を受信すると、現在のルーチンがブロックされます
要素をnilチャネルに送信します。現在のgooutineもブロックされます
閉じたチャネルに要素を送信すると、チャネルがいっぱいであるために送信操作がブロックされていても、ランタイムパニックが発生します。
複数のgoroutineが同じフルチャネルに要素のブロックを送信する場合、チャネルに空き領域があると、最初にブロックされたgoroutineが最初に起こされます。
複数のゴルーチンが同じ空のチャネルから要素のブロックを受け取る場合、チャネルに要素がある場合、最初にブロックされたゴルーチンが最初に起こされます。
Goは一度に1つのルーチンのみを起動します。
送信側からチャネルに送信された値はコピーされ、受信側は常に値のコピーを受信します。
チャネルを介して渡された値は、少なくとも1回、最大で2回コピーされます。
たとえば、1回コピーして空のチャネルに要素を送信し、少なくとも1つの受信待機中のレシーバーが既にある場合、チャネルは独自のバッファーキューをバイパスし、受信待機中の最も古いレシーバーに直接コピーします。
例:2回コピーし、フルチャネルから要素を受信し、少なくとも1人の送信者が送信を待機している場合、チャネルはバッファキューに最初に入力された要素を受信者にコピーしてから、最も古い送信者データを送信します。空の場所にコピーします。
受信側がチャネルから値タイプの値を受け取った場合、この値の変更は送信側が保持するソース値に影響を与えません。
受信側がチャネルから参照型の値を受信すると、値の変更は送信側が保持するソース値に影響します。
package main
import (
"fmt"
//"time"
)
type dataItem struct {
curl string
paramReq interface{}
resp chan error
}
type metaset struct {
key string
value string
uid string
path string
}
var dataChan = make(chan interface{}, 1)
/*
syncChan1和syncChan2的元素类型都是 struct{},struct{}代表不含任何字段的结构体类型(空结构体)
空结构体变量不占内存空间,所以所有该类型的变量都拥有相同的内存地址。
建议用于传递信号的通道都用struct{}作元素类型,除非需要传递更多的元素。
*/
func main() {
syncChan := make(chan struct{}, 2)
go func() {
for {
if elem, ok := <-dataChan; ok {
if elem, ok := elem.(dataItem); ok {
elem.resp <- nil
fmt.Printf("elem:%v\n", elem)
fmt.Printf("elem.paramReq:%v\n", elem.paramReq)
} else {
fmt.Printf("error")
}
} else {
break
}
}
fmt.Println("stopped.[receiver]")
syncChan <- struct{}{}
}()
go func() {
meta := metaset{key: "key1", value: "value1", uid: "00", path: "/root/dir1"}
data := &dataItem{curl: "/api/test", paramReq: meta, resp: make(chan error, 1)}
for i := 0; i < 5; i++ {
dataChan <- *data
//time.Sleep(time.Second)
fmt.Printf("The count map:%v.[sender]\n", data)
res := <-data.resp
fmt.Println("res:", res)
}
close(dataChan)
syncChan <- struct{}{}
}()
<-syncChan
<-syncChan
}
結果:
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
stopped.[receiver]