我想更多地了解线程的同步如何工作。在这里,我的程序功能正常,它使用完成通道进行同步。
package main
import (
. "fmt"
"runtime"
)
func Goroutine1(i_chan chan int, done chan bool) {
for x := 0; x < 1000000; x++ {
i := <-i_chan
i++
i_chan <- i
}
done <- true
}
func Goroutine2(i_chan chan int, done chan bool) {
for x := 0; x < 1000000; x++ {
i := <-i_chan
i--
i_chan <- i
}
done <- true
}
func main() {
i_chan := make(chan int, 1)
done := make(chan bool, 2)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine1(i_chan, done)
go Goroutine2(i_chan)
<-done
<-done
Printf("This is the value of i:%d\n", <-i_chan)
}
然而,当我尝试在没有任何同步的情况下运行它时。使用等待语句而没有通道来指定它何时完成,因此没有同步。
const MAX = 1000000
func Goroutine1(i_chan chan int) {
for x := 0; x < MAX-23; x++ {
i := <-i_chan
i++
i_chan <- i
}
}
func main() {
i_chan := make(chan int, 1)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine1(i_chan)
go Goroutine2(i_chan)
time.Sleep(100 * time.Millisecond)
Printf("This is the value of i:%d\n", <-i_chan)
}
它打印出错误的i值。如果你延迟等待1秒,那么它将完成并打印出正确的声明。我有点明白,在你打印i_chan
上的内容之前,两个帖子都没有完成,我只是对它的运作方式有点好奇。
答案 0 :(得分:1)
请注意您的first example would deadlock, since it never calls GoRoutine2
(OP自编辑问题以来)
如果是it calls GoRoutine2
, then the expected i
value is indeed 0。
如果没有同步,(作为in this example),则无法保证main()在完成Goroutine1()
和{{1}之前不会退出 }}。
对于1000000循环,1毫秒的等待似乎已经足够了,但同样,不能保证。
Goroutine2()
在&#34; How to Wait for All Goroutines to Finish Executing Before Continuing&#34;上查看更多内容,其中规范的方式是使用sync package’s WaitGroup
structure,如this runnable example。