Concurrency 围棋的奇怪行为

Concurrency 围棋的奇怪行为,concurrency,go,goroutine,Concurrency,Go,Goroutine,我刚刚尝试了以下代码,但结果似乎有点奇怪。它先打印奇数,然后打印偶数。我真的很困惑。我希望它能一个接一个地输出奇数和偶数,就像1、2、3、4。谁能帮我 package main import ( "fmt" "time" ) func main() { go sheep(1) go sheep(2) time.Sleep(100000) } func sheep(i int) { for ; ; i += 2 { fmt.Pr

我刚刚尝试了以下代码,但结果似乎有点奇怪。它先打印奇数,然后打印偶数。我真的很困惑。我希望它能一个接一个地输出奇数和偶数,就像1、2、3、4。谁能帮我

package main

import (
    "fmt"
    "time"
)

func main() {
    go sheep(1)
    go sheep(2)
    time.Sleep(100000)
}

func sheep(i int) {
    for ; ; i += 2 {
        fmt.Println(i,"sheeps")
    }
}

很可能您只使用一个cpu线程运行。因此,它运行第一个goroutine,然后运行第二个goroutine。如果您告诉go它可以在多个线程上运行,那么这两个线程都可以同时运行,前提是操作系统在cpu上有空闲时间这样做。您可以通过在运行二进制文件之前设置GOMAXPROCS=2来演示这一点。或者您可以尝试在sheep函数中添加一个runtime.Gosched()调用,看看这是否会触发运行时以允许另一个goroutine运行


一般来说,除非使用sync.Mutex指定特定的同步点或在通道上进行通信,否则最好不要假设两个goroutine中的操作之间具有顺序语义。

未同步的goroutine以完全未定义的顺序执行。如果你想打印出像

1 sheeps
2 sheeps
3 sheeps
....
按照这样的顺序,goroutines是错误的做法。当您不太关心事情发生的顺序时,并发性工作得很好


您可以通过同步(在
fmt.Println
调用周围锁定互斥锁或使用通道)在程序中强制命令,但这是毫无意义的,因为您可以更轻松地编写使用单个goroutine的代码。

如果您正在寻求帮助,您至少可以用描述性的方式对问题进行标题和标记。我不认为他是在假设排序,而是希望看到两个进程同时运行,而不是一个接一个地跑。我猜这应该是一个简单的测试,看看围棋程序是否酷。在这种情况下,每次打印后小睡一会也可能会起到作用,不过这显然会减慢速度。当然,对于那些在调试goroutines时发现这个问题的人来说,这是一个有用的建议,所以我把它扔了进去。