c := make(chanint) // 创建一个无缓冲的int类型的channel c := make(chanint,5) // 创建一个带缓冲的int类型的channel c <- x // 向channel c 中发送一个值 <- c // 从channel c 中接收一个值 x = <- c // 从channel c 接收一个值并将其存储到变量x中 x,ok = <- c // 从channel c 接收一个值。若channel关闭了,ok将被置为false for i := range c {...} close(c) // 关闭channel c
c := make(chanchanint) // 创建一个无缓冲的chan int类型的channel funcstream(ctx context.Context, out chan<- Value)error// 将只发送channel作为函数参数 funcspwn(...) <-chan T // 将只接收类型channel作为返回值
当需要同时对多个channel进行操作时,我们将使用另一个CSP模型提供的原语select:
1 2 3 4 5 6
select { case x := <-c1: // 从channel c1接收数据 case y,ok := <-c2: // 从channel c2接收数据,并根据ok值判断c2是否已经关闭 case c3 <- z: // 将z值发送到channel c3中 default: // 当上面的case中的channel通信无法实施时,执行该默认分支 }
funcworker() { println("worker is working...") time.Sleep(1 * time.Second) }
funcspawn(f func()) <-chan signal { c := make(chan signal) gofunc() { println("worker start to work...") f() c <- signal(struct{}{}) }() return c // 新goroutine退出的通知信号 }
funcmain() { println("start a worker...") c := spawn(worker) <-c fmt.Println("worker work done!") }
funcworker(i int) { fmt.Printf("worker %d: is working...\n", i) time.Sleep(1 * time.Second) fmt.Printf("worker %d: works done\n", i) }
funcspawnGroup(f func(i int), num int, groupSignal <-chan signal) <-chan signal { c := make(chan signal) var wg sync.WaitGroup
for i := 0; i < num; i++ { wg.Add(1) gofunc(i int) { <-groupSignal fmt.Printf("worker %d: start to work...\n", i) f(i) wg.Done() }(i + 1) }
gofunc() { wg.Wait() c <- signal(struct{}{}) }() return c }
funcmain() { fmt.Println("start a group of workers...") groupSignal := make(chan signal) c := spawnGroup(worker, 5, groupSignal) // 创建一组5个 work goroutine time.Sleep(5 * time.Second) fmt.Println("the group of workers start to work...") close(groupSignal) // 一起开始工作 <-c fmt.Println("the group of workers work done!") }
/* start a group of workers... the group of workers start to work... worker 4: start to work... worker 4: is working... worker 1: start to work... worker 2: start to work... worker 2: is working... worker 1: is working... worker 5: start to work... worker 5: is working... worker 3: start to work... worker 3: is working... worker 3: works done worker 4: works done worker 5: works done worker 1: works done worker 2: works done the group of workers work done! */
funcBenchmarkUnbufferedChan1To1Send(b *testing.B) { for n := 0; n < b.N; n++ { send("hello") } } funcBenchmarkUnbufferedChan1To1Recv(b *testing.B) { for n := 0; n < b.N; n++ { recv() } }
/*$ go test -bench . one_to_one_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkUnbufferedChan1To1Send-8 3983892 281.5 ns/op BenchmarkUnbufferedChan1To1Recv-8 4622538 272.9 ns/op PASS */
funcBenchmarkBufferedChan1To1SendCap10(b *testing.B) { for n := 0; n < b.N; n++ { send("hello") } } funcBenchmarkBufferedChan1To1RecvCap10(b *testing.B) { for n := 0; n < b.N; n++ { recv() } }
/* $ go test -bench . one_to_one_cap_10_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkBufferedChan1To1SendCap10-8 11304949 105.1 ns/op BenchmarkBufferedChan1To1RecvCap10-8 12171568 95.44 ns/op PASS $ go test -bench . one_to_one_cap_100_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkBufferedChan1To1SendCap100-8 17385675 67.87 ns/op BenchmarkBufferedChan1To1RecvCap100-8 18351138 68.77 ns/op PASS */
funcBenchmarkUnbufferedChanNToNSend(b *testing.B) { for n := 0; n < b.N; n++ { send("hello") } } funcBenchmarkUnbufferedChanNToNRecv(b *testing.B) { for n := 0; n < b.N; n++ { recv() } }
/* $ go test -bench . multi_to_multi_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkUnbufferedChanNToNSend-8 197262 5600 ns/op BenchmarkUnbufferedChanNToNRecv-8 187816 5794 ns/op PASS */
funcBenchmarkBufferedChanNToNSendCap10(b *testing.B) { for n := 0; n < b.N; n++ { send("hello") } } funcBenchmarkBufferedChanNToNRecvCap10(b *testing.B) { for n := 0; n < b.N; n++ { recv() } }
/* $ go test -bench . multi_to_multi_cap_10_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkBufferedChanNToNSendCap10-8 638821 1924 ns/op BenchmarkBufferedChanNToNRecvCap10-8 544150 1925 ns/op PASS $ go test -bench . multi_to_multi_cap_100_test.go goos: linux goarch: amd64 cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz BenchmarkBufferedChanNToNSendCap100-8 1109060 1186 ns/op BenchmarkBufferedChanNToNRecvCap100-8 877389 1269 ns/op PASS */