猿问

试图理解 Go 中的“同步”。为什么这行得通?

“这个程序应该去11,但有时它只打印1到10。修复代码并解释原因。” 是任务。我试图理解为什么这段代码有效。如果只是我将“汇编代码”添加到编译器中,那么 Print 会设法打印最后 11 个。


所以我的问题是:为什么当我在关闭后添加 wg.Wait() 时,这段代码会设法打印最后 11 个?我的头,我想在 close(ch) 之前添加 wg.Wait() 以便通道在我们完成之前不会关闭,但这给了我们一个死锁,因为我们将永远等待从通道接收更多值。


谢谢


原始代码没有与“同步”相关的代码。


func main() {


    ch := make(chan int)


    var wg sync.WaitGroup // added code


    wg.Add(1) // added code

    go Print(ch, &wg) // added code (&wg)


    for i := 1; i <= 11; i++ {

        ch <- i

    }


    close(ch)

    wg.Wait() // added code


}


// Print prints all numbers sent on the channel.

// The function returns when the channel is closed.

func Print(ch <-chan int, wg *sync.WaitGroup) { // added code (wg *sync.WaitGroup)

    for n := range ch { // reads from channel until it's closed

        fmt.Println(n)

    }

    wg.Done() // added code

}


MMMHUHU
浏览 86回答 1
1回答

慕尼黑的夜晚无繁华

如果没有wg.Wait,主 goroutine 可能会在第二个 goroutine 完成打印之前终止。您正在使用没有缓冲区的通道,因此每当主 goroutine 通过通道发送值时,goroutine 都会接收该值。但是,这并不能保证会打印该值。主 goroutine 可以在 print 完成之前开始期待,并且可以终止程序。等待组是必要的,以确保主 goroutine 等待打印 goroutine 完成。
随时随地看视频慕课网APP

相关分类

Go
我要回答