doudi2229 2017-10-19 04:05
浏览 80
已采纳

如何理解golang内存模型中的通道通信规则?

Learning golang on the way, I got a little confused when trying to understand the channel communications described in the memory model spec as below:

  1. A send on a channel happens before the corresponding receive from that channel completes.
  2. The closing of a channel happens before a receive that returns a zero value because the channel is closed.
  3. A receive from an unbuffered channel happens before the send on that channel completes.
  4. The kth receive on a channel with capacity C happens before the k+Cth send from that channel completes.

The first 2 rules are clear and easy to understand, while I really got confused about the 3rd rule, which seems opposite to others... Did I miss anything special about unbuffered channel? Or am I correct If I take it like the below with the example in the spec:

var c = make(chan int)
var a string

func f() {
    a = "hello, world"
    <-c    // A
}
func main() {
    go f()
    c <- 0 // B
    print(a)
}

For an unbuffered channel, the send operation(B) is blocked until the receiver gets ready to receive the value(A)? (like: B starts and does not return until A executes) Is it accurate?

And I find the following statements in Effective Go spec, but there's still discrepancy from my understanding... So can someone please explain this in a simple and straightforward way?

Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.

  • 写回答

2条回答 默认 最新

  • duanjiagu0655 2017-10-19 04:59
    关注

    The sentence you've highlighted is the simple explanation you are looking for.

    If the channel is unbuffered, the sender blocks until the receiver has received the value.

    It's another way of saying point 3:

    A receive from an unbuffered channel happens before the send on that channel completes.

    When you send on an unbuffered channel, the sender blocks until the receiver has taken the value. This means the receive happens before the send completes.

    A buffered channel is different, because the value has somewhere to go. If you're still confused, an example might help:

    Say I want to leave a package at your house:

    • If the channel is buffered, you have somewhere for me to leave the package - perhaps a mailbox. This means I can complete my task of giving you the package (sending on the channel) before you receive it (when you check your mailbox).
    • If the channel is not buffered, I have to wait by your front door until you come and take the package off me. You receive the package before I am done with my task of delivering it to you.

    For an unbuffered channel, the send operation(B) is blocked until the receiver gets ready to receive the value(A)? (like: B starts and does not return until A executes) Is it accurate?

    Yes. This is correct.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动