Golang - 什么是Channel,带缓冲区和不带缓冲区的区别,为什么它可以做到线程安全


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是不能closepanic: 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。 

对未初始化的的chan进行读(接收)写(发送),会怎么样?为什么?【查看原文

对已经关闭的chan进行读写,会怎么样?为什么?【查看原文


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM