Channels in Go
谢权 · · 1626 次点击 · · 开始浏览Go的Goroutine能够让我们并行的运行一些代码。但是要有效的利用它,需要一些额外的工作。当进程完成创建,我们应该能够将数据传递到正在运行的进程,我们也应该能够获取数据从正在运行的进程,channels 做到了这一点并且能够很好的与goroutines工作。
我们可以把Channel想象成一个通道管或定义的大小和容量的传输带,一边可以往管道上面存放东西,另外一边可以将其取出
Channels用来同步并发执行的函数并提供它们某种传值交流的机制。Channels的一些特性:通过channel传递的元素类型、容器(或缓冲区)和传递的方向由"<-"操作符指定。你可以使用内置函数 make分配一个channel:
我们可以通过<- 操作符发送或接收的数据
查看一个完整的示例:
输出的结果:
其实并不建议将goroutine放在 for 循环中
对比上面的输出结果:
缓冲
为了避免存在一个channel的缓冲区所有读取操作都在没有锁定的情况下顺利完成(如果缓冲区是空的)并且写入操作也顺利结束(缓冲区不满),这样的channel被称作非同步的channel。下面是一个用来描述这两者区别的例子:
现在我们提供一个缓冲区给输出信息的channel,例如:定义初始化行将被改为:message := make(chan string, 2)。这次程序输出将变为:
这里我们看到所有的写操作的执行都不会等待第一次对缓冲区的读取操作结束,channel允许储存所有的三条信息。通过修改channel容器,我们通过可以控制处理信息的总数达到限制系统输出的目的。
死锁
我们会看到编译器报错:
这个错误就是我们所知的死锁. 在这种情况下,两个goroutine互相等待对方释放资源,造成双方都无法继续运行。GO语言可以在运行时检测这种死锁并报错。这个错误是因为锁的自身特性产生的。
代码在次以单线程的方式运行,逐行运行。向channel写入的操作(c <- 42)会锁住整个程序的执行进程,因为在同步channel中的写操作只有在读取器准备就绪后才能成功执行。然而在这里,我们在写操作的下一行才创建了读取器。
为了使程序顺利执行,我们需要做如下改动:
运行上面代码 就可以看到正常输出42了。
参考文献:http://golangtutorials.blogspot.hk/2011/06/channels-in-go.html
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
Go的Goroutine能够让我们并行的运行一些代码。但是要有效的利用它,需要一些额外的工作。当进程完成创建,我们应该能够将数据传递到正在运行的进程,我们也应该能够获取数据从正在运行的进程,channels 做到了这一点并且能够很好的与goroutines工作。
我们可以把Channel想象成一个通道管或定义的大小和容量的传输带,一边可以往管道上面存放东西,另外一边可以将其取出
Channels用来同步并发执行的函数并提供它们某种传值交流的机制。Channels的一些特性:通过channel传递的元素类型、容器(或缓冲区)和传递的方向由"<-"操作符指定。你可以使用内置函数 make分配一个channel:
我们可以通过<- 操作符发送或接收的数据
查看一个完整的示例:
输出的结果:
其实并不建议将goroutine放在 for 循环中
对比上面的输出结果:
缓冲
为了避免存在一个channel的缓冲区所有读取操作都在没有锁定的情况下顺利完成(如果缓冲区是空的)并且写入操作也顺利结束(缓冲区不满),这样的channel被称作非同步的channel。下面是一个用来描述这两者区别的例子:
现在我们提供一个缓冲区给输出信息的channel,例如:定义初始化行将被改为:message := make(chan string, 2)。这次程序输出将变为:
这里我们看到所有的写操作的执行都不会等待第一次对缓冲区的读取操作结束,channel允许储存所有的三条信息。通过修改channel容器,我们通过可以控制处理信息的总数达到限制系统输出的目的。
死锁
我们会看到编译器报错:
这个错误就是我们所知的死锁. 在这种情况下,两个goroutine互相等待对方释放资源,造成双方都无法继续运行。GO语言可以在运行时检测这种死锁并报错。这个错误是因为锁的自身特性产生的。
代码在次以单线程的方式运行,逐行运行。向channel写入的操作(c <- 42)会锁住整个程序的执行进程,因为在同步channel中的写操作只有在读取器准备就绪后才能成功执行。然而在这里,我们在写操作的下一行才创建了读取器。
为了使程序顺利执行,我们需要做如下改动:
运行上面代码 就可以看到正常输出42了。
参考文献:http://golangtutorials.blogspot.hk/2011/06/channels-in-go.html