Can you guarantee data consistency in one write to many read channel in golang?

xuanbao · 2016-04-12 01:30:37 · 563 次点击    
这是一个分享于 2016-04-12 01:30:37 的资源,其中的信息可能已经有所发展或是发生改变。

If I have 2 5 goroutine for read, and 1 goroutine for write, is there a way to make sure that every goroutine gets the entire write data?

For example.

In the following code whenever I write to main thread, one and only one goroutine gets the value.

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    c := make(chan int)
    var w sync.WaitGroup
    w.Add(5)

    for i := 1; i <= 5; i++ {
        go func(i int, ci <-chan int) {
            j := 1
            for v := range ci {
                time.Sleep(time.Millisecond)
                fmt.Printf("%d.%d got %d\n", i, j, v)
                j += 1
            }
            w.Done()
        }(i, c)
    }

    for i := 1; i <= 25; i++ {
        c <- i
    }
    close(c)
    w.Wait()
}

I want to make sure all goroutine gets the entire value 1-25 in a non blocking manner. For example one goroutine can read the entire 1-25 and finish processing, while others can still be reading all the data.

If I want to do this, do I have to create 25 channels? Or is there more subtle way of maintaining the desired behavior.


评论:

gdey:

Yes, you would need to create 5 channels, make it buffered so it does not block, one for each goroutine, and send the values to each channel.

In the play version I increased the sleep based on the i of the goroutine, to show that go routines complete and don't wait.

Here is go playground

package main
import (
    "fmt"
    "sync"
    "time"
)
func main() {
    var chans [5]chan int
    for i := range chans {
        chans[i] = make(chan int, 25)
    }
    var w sync.WaitGroup
    w.Add(5)
    for i := 0; i < 5; i++ {
        go func(i int, ci <-chan int) {
            j := 1
            for v := range ci {
                time.Sleep(time.Millisecond)
                fmt.Printf("%d.%d got %d\n", i, j, v)
                j += 1
            }
            w.Done()
        }(i+1, chans[i])
    }
    for i := 1; i <= 25; i++ {
        for _, c := range chans {
            c <- i
        }
}
    for _, c := range chans {
        close(c)
    }
    w.Wait()
}
icholy:

When there are many consumers the delivery semantics are basically round robin (kinda), if you want to do a fan-out pattern you have to do it yourself.


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

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