duanbiaoshu2021 2017-11-03 00:55
浏览 87
已采纳

Golang-异步功能中缓冲通道的范围可以同步吗?

I am trying something similar to the below pattern:

func sendFunc(n int, c chan int) {
    for i := 0; i < n; i++ {
        c <- i
        fmt.Println("Pushed")
    }
    close(c)
}

func main() {
    c := make(chan int, 10)
    go sendFunc(10, c)
    // Receive from the channel
    for i := range c {
        fmt.Println(i)
    }
}

The output appears to be sync, like this:

Pushed
Pushed
Pushed
Pushed
Pushed
Pushed
Pushed
Pushed
Pushed
Pushed
0
1
2
3
4
5
6
7
8
9

Does that mean range over for loop is actually receiving data synchronously?

But if I change the buffered channel to a non-buffered channel:

c := make(chan int)

the result seems to be async:

Pushed
0
1
Pushed
Pushed
2
3
Pushed
Pushed
4
5
Pushed
Pushed
6
7
Pushed
Pushed
8
9
Pushed

which one is better? (what about the performance diff?)

Updated

So my scenario is that: in the receiverFunc a request will be made every time new data is received from the sendFunc(), the result shows that the scheduler does not start receiving until all data has been sent to the channel (given a buffered channel with enough buffer space). Therefore I ended up using the non-buffered channel so that the time for waiting for the respond and the time for processing data in the sendFunc() can overlap which provides a better performance.

  • 写回答

1条回答 默认 最新

  • dqwd71332 2017-11-03 12:29
    关注

    As Cerise Limón already stated: this is an effect of how the runtime schedules go routines. Basically a go routine is run as long as it doesn't block or returns. So the call go sendFunc(10, c) will execute until it blocks or returns. If you put a <-time.After(1) in the sendFunc, the function will suddenly block and you will have the effect that the scheduler will schedule another routine.

    here is a little example on the playground: https://play.golang.org/p/99vJniOf3_

    The question which one is better is hard to answer. And disclaimer: I am by far not an expert on this, but I guess it is a tradeoff. While a smaller buffer reduces the time a single message stays in a buffer, it triggers a re-scheduling of go routines, which general costs some time.

    A larger buffer can on the other hand increase the message latency through the buffer but on the other hand improve the throughput. Also you can preproduce a lot of messages, which can be useful if you have some static overhead that is the same for one or many messages (e.g. requesting a single line of input vs requesting multiple lines of input).

    Have this explanation of the scheduler https://rakyll.org/scheduler/.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog