为了更多地了解Go,我一直在玩goroutines,并注意到了一些东西 - 但我不确定我到底看到了什么,并希望有人可以解释以下行为.
以下代码完全符合您的期望:
package main
import (
"fmt"
)
type Test struct {
me int
}
type Tests []Test
func (test *Test) show() {
fmt.Println(test.me)
}
func main() {
var tests Tests
for i := 0; i < 10; i++ {
test := Test{
me: i,
}
tests = append(tests, test)
}
for _, test := range tests {
test.show()
}
}
Run Code Online (Sandbox Code Playgroud)
并按顺序打印0 - 9.
现在,当代码改变如下所示时,它总是先返回最后一个 - 无论我使用哪个数字都无关紧要:
package main
import (
"fmt"
"sync"
)
type Test struct {
me int
}
type Tests []Test
func (test *Test) show(wg *sync.WaitGroup) {
fmt.Println(test.me)
wg.Done()
}
func main() {
var tests Tests
for i := 0; i < 10; i++ {
test := Test{
me: i,
}
tests = append(tests, test)
}
var wg sync.WaitGroup
wg.Add(10)
for _, test := range tests {
go func(t Test) {
t.show(&wg)
}(test)
}
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
这将返回:9 0 1 2 3 4 5 6 7 8
循环的迭代顺序没有改变,所以我猜它与goroutines有关...基本上,我试图理解为什么它的行为像这样...我明白goroutines可以在一个不同于它们产生的顺序,但是,我的问题是为什么它总是这样运行.好像有一些非常明显的东西,我想念......
正如预期的那样,输出是伪随机的,
package main
import (
"fmt"
"runtime"
"sync"
)
type Test struct {
me int
}
type Tests []Test
func (test *Test) show(wg *sync.WaitGroup) {
fmt.Println(test.me)
wg.Done()
}
func main() {
fmt.Println("GOMAXPROCS", runtime.GOMAXPROCS(0))
var tests Tests
for i := 0; i < 10; i++ {
test := Test{
me: i,
}
tests = append(tests, test)
}
var wg sync.WaitGroup
wg.Add(10)
for _, test := range tests {
go func(t Test) {
t.show(&wg)
}(test)
}
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
输出:
$ go version
go version devel +af15bee Fri Jan 29 18:29:10 2016 +0000 linux/amd64
$ go run goroutine.go
GOMAXPROCS 4
9
4
5
6
7
8
1
2
3
0
$ go run goroutine.go
GOMAXPROCS 4
9
3
0
1
2
7
4
8
5
6
$ go run goroutine.go
GOMAXPROCS 4
1
9
6
8
4
3
0
5
7
2
$
Run Code Online (Sandbox Code Playgroud)
你在围棋操场上跑步吗?Go Playground 在设计上是确定性的,这使得缓存程序变得更加容易。
或者,您是否以runtime.GOMAXPROCS = 1运行?这一次按顺序运行一件事。这就是 Go 游乐场的作用。