跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 协程执行问题请教
未分類
2 5 月 2020

协程执行问题请教

协程执行问题请教

資深大佬 : davidyanxw 19

package main

import (
“fmt”
“time”
)

var x = 0

func main() {
var num = 123
var p = &num
c := make(chan int)
go func() {
c <- *p + x // 1. 返回 123
// c <- *p // 2. 返回 789
}()
time.Sleep(time.Second)
num = 789
fmt.Println(<-c)

}

子协程,执行 1 返回 123,执行 2 返回 789
没看出来有什么差别啊?

大佬有話說 (10)

  • 資深大佬 : kaifang

    有区别,
    1 进行了运算,取运算后的结果,你加了 1 秒的延时,很明显当时的 num 的值为 123,所以输出是 123,如果去掉延时,则为 789
    2 一直指向 num 的地址,从通道里读的时候读的是 789

  • 資深大佬 : bwangel

    time.Sleep 不能保证 goroutine 一定比 main 先执行,如果想要让 Goroutine 比 main 先执行的话,可以通过 waitGroup 来同步:

    https://gist.github.com/bwangelme/5e71895d40130521b71828cef72adc1f

  • 資深大佬 : MoYi123

    c <- *p + x // 1. 返回 123 等于 tmp:= *p + x ; c<- tmp ,因为 chan 的 size 是 0 所以要等到主进程到 fmt.Println(<-c)时才会运行 c<- tmp

  • 資深大佬 : blip

    ”By default channels are unbuffered, meaning that they will only accept sends (chan <-) if there is a corresponding receive (<- chan) ready to receive the sent value“
    @MoYi123 正解

  • 資深大佬 : useben

    @MoYi123 正解, 1 2 答的不是这个问题

  • 主 資深大佬 : davidyanxw

    @blip
    按照这个说法的话,应该两个值都会返回 123 才对啊?
    为啥第 1 种返回 123,第 2 种返回 789

  • 主 資深大佬 : davidyanxw

    @kaifang 1 运算了,2 为啥不运算呢?

  • 資深大佬 : kaifang

    @davidyanxw #7 2,向通道发送的 num 的地址,此时通道是阻塞的,过一秒后 num 因为赋值 789 地址发生改变,然后从通道里读取 num 值是 789

  • 資深大佬 : blip

    @davidyanxw good ask, 我觉得我之前没有抓住对的点,我对 unbuffered channel 的解释其实并没有回答这个问题,这里的重点其实是
    1, *p+x 会 create 一个新的 int ( 123 )存放在另一个地址,这个地址存放的值没有改变过
    2,*p 会一直等于 num 的地址所存储的值,这个值在代码中被更改为 789
    所以才会造成两个 case 结果不同

  • 主 資深大佬 : davidyanxw

    @blip
    感谢

    ch <- expression

    expression 计算的时机是问题的关键。
    具体的细节,希望大牛们给详细说说

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具