文章目录
channels
channel存在以下四个特性
- goroutine-safe
- store and pass values between goroutines
- provide FIFO semantics
- can cause goroutines to block and unblock
How to use Channels
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 3)
go func() {
for i := 0; i < 10; i++ {
ch <- i
time.Sleep(500 * time.Millisecond)
}
close(ch)
}()
value := <-ch
fmt.Println(value)
for value := range ch {
fmt.Println(value)
}
}
Channel源码解析
基于的go版本为1.13,源代码位于runtime/chan.go
代码入口
go的编译器对channel进行处理,从汇编中可以看到具体调用的函数。下面截取了部分的关键代码。
$ go tool compile -S channel.go > channel.s
$ vim channel.s
0x0035 00053 (channel.go:9) CALL runtime.makechan(SB)
0x003e 00062 (channel.go:12) CALL runtime.chansend1(SB)
0x0078 00120 (channel.go:18) CALL runtime.chanrecv1(SB)
0x0067 00103 (channel.go:15) CALL runtime.closechan(SB)
从上面可以看出
- 当调用make(chan int,4)时,调用的是runtime下的makechan函数
- 当调用ch <- i时,调用的是runtime下的chansend1函数
- 当调用value := <-ch时,调用的是runtime下的chanrecv函数
channel的结构体
type hchan struct {
qcount uint // channel的队列中数据的总数,会随着<-和 -> 变化
dataqsiz uint // channel循环数组的长度,
buf unsafe.Pointer // 指向底层循环数组的指针,只针对