0

我刚刚尝试了以下代码,但结果似乎有点奇怪。它先打印奇数,然后打印偶数。我真的很困惑。我曾希望它一个接一个地输出奇数和偶数,就像 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")
    }
}
4

2 回答 2

6

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

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

于 2012-06-26T16:03:59.207 回答
3

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

1 sheeps
2 sheeps
3 sheeps
....

按照这个确切的顺序,goroutines 是错误的方法。当您不太关心事情发生的顺序时,并发性很好。

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

于 2012-06-26T19:32:13.510 回答