Go语言中线程的同步
Synchronisation of threads in Go lang
我想更多地了解线程同步在 go 中的工作原理。下面是我的程序的一个功能版本,它使用一个完成的通道进行同步。
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
上的内容之前,两个线程都没有完成我只是有点好奇这是如何工作的。
请注意,您的 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()
之前不退出并且Goroutine2()
.
对于 1000000 次循环,1 毫秒的等待似乎就足够了,但同样不能保证。
func main() {
i_chan := make(chan int, 1)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine2(i_chan)
go Goroutine1(i_chan)
time.Sleep(1 * time.Millisecond)
Printf("This is the value of i:%d\n", <-i_chan)
}
在“How to Wait for All Goroutines to Finish Executing Before Continuing", where the canonical way is to use the sync package’s WaitGroup
structure, as in this runnable example.
查看更多内容
我想更多地了解线程同步在 go 中的工作原理。下面是我的程序的一个功能版本,它使用一个完成的通道进行同步。
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
上的内容之前,两个线程都没有完成我只是有点好奇这是如何工作的。
请注意,您的 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()
之前不退出并且Goroutine2()
.
对于 1000000 次循环,1 毫秒的等待似乎就足够了,但同样不能保证。
func main() {
i_chan := make(chan int, 1)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine2(i_chan)
go Goroutine1(i_chan)
time.Sleep(1 * time.Millisecond)
Printf("This is the value of i:%d\n", <-i_chan)
}
在“How to Wait for All Goroutines to Finish Executing Before Continuing", where the canonical way is to use the sync package’s WaitGroup
structure, as in this runnable example.