Channels in Go

谢权 · · 983 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go的Goroutine能够让我们并行的运行一些代码。但是要有效的利用它,需要一些额外的工作。当进程完成创建我们应该能够数据传递正在运行进程我们也应该能够获取数据正在运行进程,channels 做到了这一点并且能够很好的与goroutines工作。

我们可以把Channel想象成一个通道定义大小容量的传输带,一边可以往管道上面存放东西,另外一边可以将其取出

channels

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

Channels in Go

有疑问加站长微信联系(非本文作者)

本文来自:谢权SELF

感谢作者:谢权

查看原文:Channels in Go

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

983 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传