【发布时间】:2015-01-23 15:47:15
【问题描述】:
我想更多地了解线程同步在 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 上的内容之前,两个线程都没有完成,我只是有点好奇这是如何工作的。
【问题讨论】:
-
您在第一个示例中是否错过了对
Goroutine2的呼叫?在您的第二个示例中,Goroutine2的定义在哪里?您在第二个示例中提到了有关“等待语句”的内容——什么是“等待语句”,它在哪里? -
注意:Go 没有“线程”作为语言结构。你的意思是“goroutines”吗?
-
@BraveNewCurrency goroutines 是我对绿色线程的理解,因此您可以编写关键字 go 并启动一个新的绿色线程。对吗?
-
@Amit Kumar Gupta。是的,那里有一些复制意大利面错误。我现在确实修好了。通过等待语句,它是最后的睡眠语句。所以基本上它并没有真正等待任何事情完成它只是让主线程进入睡眠状态。
标签: multithreading go