Channel的理解
Channel是Go中的一个核心类型,可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication),Channel也可以理解是一个先进先出的队列,通过管道进行通信。
Golang的Channel,发送一个数据到Channel和从Channel接收一个数据都是原子性的。
Go的设计思想就是,不要通过共享内存来通信,而是通过通信来共享内存,前者就是传统的加锁,后者就是Channel。
也就是说,设计Channel的主要目的就是在多任务间传递数据,所以本身就是安全的。
带缓冲区和不带缓冲区的区别
1)缓冲区大小不同
不带缓冲区的chan缓冲区大小是0,带缓冲区的chan缓冲区至少是1
2)运行方式不同
带缓冲区的channel:【同步】
写入阻塞条件:缓冲区满;
取出阻塞条件:缓冲区没有数据。
不带缓冲区的channel:【异步】
写入阻塞条件:同一时间没有另外一个线程对该chan进行读操作;
取出阻塞条件:同一时间没有另外一个线程对该chan进行写操作。
channel存在3种状态
nil:未初始化的状态,只进行了声明,或者手动赋值为nil,nil状态的chan是不能close(panic: close of nil channel);
active:正常的channel,可读或者可写 ;
closed:已关闭,千万不要误认为关闭channel后,channel的值是nil,关闭的状态的chan仍然可以读值(取值),但不能写值(会报panic: send on closed channel)。
func main() { var a chan int fmt.Println(a) // <nil>
a = make(chan int) close(a) fmt.Println(a) // 0xc00003e060
}
channel可进行3种操作
总结
发生 panic 的情况有三种:向一个关闭的 channel 进行写操作;重复关闭一个 channel;关闭一个 nil 的 channel。
发生 阻塞(死锁)的情况:读、写一个 nil的 channel。