网站首页 > 技术文章 正文
ch 通道在go的应用
通道是 Go 中的一种同步原语,源自 Hoare 的 CSP。虽然它们可用于同步内存访问,但它们最适合用于在 goroutine 之间传递信息,通道的默认值:nil
声明一个通道来读取和发送
stream := make(chan interface{})声明只能读取的单向通道
stream := make(<-chan interface{})声明只能发送的单向通道
stream := make(chan<- interface{})
不经常看到实例化通道单向,只在函数的参数中,很常见,因为 Go 将它们隐式转换
var receiveChan <-chan interface{}
var sendChan chan<- interface{}
dataStream := make(chan interface{})
// Valid statements:
receiveChan = dataStream
sendChan = dataStream收到
<-stream
发送
stream <- "Hello world"
如果通道关闭,则在通道上测距 for range 会中断循环
intStream := make(chan int)
go func() {
defer close(intStream)
for i := 1; i <= 5; i++ {
intStream <- i
}
}()
for integer := range intStream {
fmt.Printf("%v ", integer)
}无缓冲通道
无缓冲通道上的发送操作会阻塞发送 goroutine,直到另一个 goroutine 在同一通道上执行相应的接收;那时,值被传递,两个 goroutines 可以继续。
另一方面,如果事先尝试接收操作,则接收 goroutine 将被阻塞,直到另一个 goroutine 在同一通道上执行发送。通过无缓冲通道的通信使发送和接收 goroutines 同步。
因此,无缓冲通道有时被称为同步通道。当通过无缓冲通道发送值时,值的接收发生在发送 goroutine 再次唤醒之前。
在讨论并发性时,当我们说 x 发生在 y 之前时,我们不仅仅意味着 x 在时间上发生在 y 之前;我们的意思是这是有保证的,您之前的所有效果(例如变量更新)都将完成,您可以指望它们。当 x 不在 y 之前或 y 之后出现时,我们说 x 与 y 并发。这并不是说 x 和 y 一定是同时的;
buffered channel
var dataStream chan interface{}
dataStream = make(chan interface{}, 4)读取和发送通道空导致死锁
var dataStream chan interface{}
<-dataStream // This panics with: fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive (nil chan)]:
main.main()
/tmp/babel-23079IVB/go-src-23079O4q.go:9 +0x3f
exit status 2var dataStream chan interface{}
dataStream <- struct{}{} // This produces: fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send (nil chan)]:
main.main()
/tmp/babel-23079IVB/go-src-23079dnD.go:9 +0x77
exit status 2关闭通道会引起panic
var dataStream chan interface{}
close(dataStream) // This produces: panic: close of nil channelgoroutine 1 [running]:
panic(0x45b0c0, 0xc42000a160)
/usr/local/lib/go/src/runtime/panic.go:500 +0x1a1
main.main()
/tmp/babel-23079IVB/go-src-230794uu.go:9 +0x2a
exit status 2 Yipes! This is probably总结
操作 | 通道状态 | 结果 |
读 | 零 | 堵塞 |
_ | 开而不空 | 价值 |
_ | 打开和空 | 堵塞 |
_ | 关 | 默认值,假 |
_ | 只写 | 编译错误 |
写 | 零 | 堵塞 |
_ | 开放和完整 | 堵塞 |
_ | 开而不满 | 写值 |
_ | 关闭 | panic |
_ | 只接收 | 编译错误 |
关 | 零 | panic |
_ | 开而不空 | 关闭频道;读取成功直到通道被耗尽,然后读取产生默认值 |
_ | 打开和空 | 关闭频道;读取产生默认值 |
_ | 关闭 | panic |
- 上一篇: 浅谈Go语言的并发控制
- 下一篇: Go 并发编程的思考
猜你喜欢
- 2024-12-01 Go 并发可视化解释 — 通道
- 2024-12-01 Go并发编程面试15题
- 2024-12-01 Go 语言并发编程实践:从入门到进阶
- 2024-12-01 Go语言编写的简单并发编程示例
- 2024-12-01 并发编程的奇技淫巧:Go语言调度器的内在工作机制
- 2024-12-01 Goroutine 并发调度模型深度解析之手撸一个高性能 goroutine 池
- 2024-12-01 每天2分钟学习GO语言编程(十九)并发简明教程
- 2024-12-01 并发编程,程序员必修课,来看go语言的巧妙实现,极为干练
- 2024-12-01 Go项目中如何限制并发数?Atomic必须掌握
- 2024-12-01 Go语言并发入门
- 最近发表
-
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
- [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
- 超详细手把手搭建在ubuntu系统的FFmpeg环境
- Nginx运维之路(Docker多段构建新版本并增加第三方模
- 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
- Go 人脸识别教程_piwigo人脸识别
- 安卓手机安装Termux——搭建移动服务器
- ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
- Rust开发环境搭建指南:从安装到镜像配置的零坑实践
- Windows系统安装VirtualBox构造本地Linux开发环境
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (73)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)
