这篇文章主要讲解了“什么是go Channel”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是go Channel”吧!
Channel作为Go的核心数据结构和Goroutine之间的通信方式,Channel是Go高并发变编程模型的重要组成部分。通常chan关键字会与range或者select组合使用。
在java或者其它的一些语言中,在编写多线程的代码时,最被人诟病的写法就是:通过共享内存的方式进行通信。通常对于这一类的代码,我们建议通过通信的方式共享内存,例如java中我们可以让线程阻塞来获取互斥锁。但是在Go的语言设计时,就与上诉的模型有所偏差。
Goroutine 和 Channel 分别对应 CSP 中的实体和传递信息的媒介,Goroutine 之间会通过 Channel 传递数据
在Go中,虽然也和java或者其他语言一样使用互斥锁来进行通信,但是Go提供了另外一种并发模型,通信顺序进程(Communicating sequential processes,CSP)。可以让Goroutine之间使用Channel传递数据。
特点:
这是chan的数据结构
type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters // lock protects all fields in hchan, as well as several // fields in sudogs blocked on this channel. // // Do not change another G's status while holding this lock // (in particular, do not ready a G), as this can deadlock // with stack shrinking. lock mutex}
新建chan
//无缓冲管道 c1 := make(chan int) //缓冲管道 c2 := make(chan int, 10)
发送数据
c := make(chan int, 10)c <- 1
接收数据
c := make(chan int, 10)c <- 1for v := range c { fmt.Println(v)}// or for { select { case <-c: fmt.Println("done") return default: fmt.Println("c waiting") }}
关闭通道
c := make(chan int, 10)close(c)
注意事项:
往一个已经被close
的channel中继续发送数据会导致run-time panic
往nil channel
中发送数据会一致被阻塞着
从一个nil channel
中接收数据会一直被block
从一个被close
的channel
中接收数据不会被阻塞,而是立即返回,接收完已发送的数据后会返回元素类型的零值(0
)
当使用select
的时候,如果同时有多个协程同时返回,那么这时候会随机取一个协程触发case里的逻辑
感谢各位的阅读,以上就是“什么是go Channel”的内容了,经过本文的学习后,相信大家对什么是go Channel这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/superhreojim/blog/5023529