goroutine 调用行之后的行是否比 goroutine 的第一行更早开始?
Does the line following the goroutine calling line starts earlier than first line of goroutine?
代码如下:
import "fmt"
func main() {
messages := make(chan string, 1)
go func(c chan string) {
c <- "Hi"
}(messages)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
}
输出no message received
。
或此代码:
import (
"fmt"
"time"
)
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
}("going")
time.Sleep(time.Second)
fmt.Println("done")
}
意外打印
going
goroutine : 0
goroutine : 1
goroutine : 2
尽管具有 going
的 goroutine 调用晚于计数器。为什么?
多个协程之间没有执行顺序保证。只有当两个 goroutines 使用通道交换数据,或使用另一种同步机制进行同步时,才能建立顺序保证。在您的情况下,您碰巧观察到一个 goroutine 在另一个 goroutine 之前碰巧 运行 的执行。当你多次 运行 时,你可能会观察到不同的顺序。
代码如下:
import "fmt"
func main() {
messages := make(chan string, 1)
go func(c chan string) {
c <- "Hi"
}(messages)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
}
输出no message received
。
或此代码:
import (
"fmt"
"time"
)
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
}("going")
time.Sleep(time.Second)
fmt.Println("done")
}
意外打印
going
goroutine : 0
goroutine : 1
goroutine : 2
尽管具有 going
的 goroutine 调用晚于计数器。为什么?
多个协程之间没有执行顺序保证。只有当两个 goroutines 使用通道交换数据,或使用另一种同步机制进行同步时,才能建立顺序保证。在您的情况下,您碰巧观察到一个 goroutine 在另一个 goroutine 之前碰巧 运行 的执行。当你多次 运行 时,你可能会观察到不同的顺序。