2013-02-27 54 views
20

缓冲通道的用途是什么?如果我想要多个并行操作,我可以使用默认的同步通道eq。何时使用缓冲通道?

package main 
import "fmt" 
import "time" 

func longLastingProcess(c chan string) { 
    time.Sleep(2000 * time.Millisecond) 
    c <- "tadaa" 
} 

func main() { 
    c := make(chan string) 
    go longLastingProcess(c) 
    go longLastingProcess(c) 
    go longLastingProcess(c) 
    fmt.Println(<- c) 
} 

增加缓冲区大小的实际情况是什么?

回答

0

这是一个很难回答的问题b/c程序不正确:它从一个goroutine收到信号后退出,但有三个已经启动。缓冲频道使其没有什么不同。

编辑:例如,这里是关于频道buffers的一般性讨论。还有一些exercise。和一个book chapter差不多。

+0

嘿,问题是关于缓冲通道的真实生活使用场景。上面的例子实际上只是一个例子。 – Dante 2013-02-27 13:45:34

+0

使用缓冲通道很大程度上取决于执行的任务。查看更新的答案。 – zzzz 2013-02-27 14:10:56

3

只要还有空间,缓冲的频道对于发件人而言是非阻塞的。这可以提高响应能力和吞吐量。

在一个缓冲通道上发送多个项目可确保按照发送顺序处理它们。

从有效围棋(与实施例):“A buffered channel can be used like a semaphore, for instance to limit throughput.

一般而言,有许多用例和信道使用的模式,所以这不是一个排气答案。

8

为了给一个单一的,稍微更具体的用例:

假设你希望你的频道来表示任务队列,使任务调度器可以将作业发送到队列和工作线程可以消耗通过在频道中接收它的工作。

假设进一步说,尽管一般情况下您希望及时处理每个作业,但工作人员完成任务所需的时间比调度程序对其进行调度要花费更长的时间。

拥有一个缓冲区允许调度程序在队列中存放作业,并且仍然对用户输入(或网络流量或其他)作出响应,因为它不必在每次调度任务时工作人员准备就绪时才进入休眠状态。相反,它涉及其业务,并相信工人在较安静的时期追赶。

如果你想要一个甚至更具体的例子来处理一个特定的软件,那么我会看看我能做什么,但我希望这可以满足你的需求。

12

通常,通道中的缓冲对性能的原因是有益的。

如果一个程序是使用事件流或数据流的方法设计的,信道提供用于事件的装置的一个过程和另一个(I使用的术语过程在同样的意义如托尼霍尔的之间通过(CSP),即有效地与同义。)。通信顺序处理(CSP),即,与常规有效同义。

  • 有时候程序需要其组件保持锁步同步。在这种情况下,需要无缓冲的频道。

  • 否则,向通道添加缓冲通常是有益的。这应该被看作是一个优化步骤(如果没有设计,死锁仍然是可能的)。

  • 通过使用具有小缓冲区的通道可以实现新颖的节流结构(example)。

  • 有特殊地重写或在奥坎姆和用于固定的,否则可能发生死锁的处理的循环(或环)的特殊情况下JCSP使用的信道的有损耗的形式。这也可以通过写一个覆盖goroutine缓冲区(example)。

您不应该仅仅为了解决死锁而添加缓冲。如果程序死锁,通过从零缓冲开始并考虑依赖关系来解决问题要容易得多。然后添加缓冲,当你知道它不会死锁。

您可以在构图上构建goroutines - 也就是说,goroutine本身可以包含goroutines。这是CSP的一项功能,可以大大提高可扩展性。在设计组的外部使用作为独立组件时,一组goroutine之间的内部渠道并不重要。这个原则可以在越来越大的范围内反复应用。

+2

它们也可以用来确保一个goroutine退出,例如在'time.After'中,它被用来使得无论客户端是否在等待值,它都可以发送并返回。缓冲也用于例如'os/signal'包的客户端,因为API无法阻止通知。 – 2013-03-02 02:51:54

2

如果通道的接收者总是比发送者慢,那么最终会消耗任何大小的缓冲区。这会给你留下一个频道,像无缓冲频道那样频繁地暂停你的去路,所以你不妨使用无缓冲的频道。

如果接收器通常比发送器快,除了偶尔发生突发,缓冲通道可能会有帮助,并且缓冲区应该设置为通过运行时测量可以达到的典型突发的大小。

作为缓冲通道的替代方案,最好只是通过通道发送包含数组的数组或结构来处理突发/批处理。