奇怪的Go协程行为

huangapple go评论72阅读模式
英文:

Strange behavior of go routine

问题

我刚刚尝试了以下代码,但结果似乎有点奇怪。它先打印奇数,然后再打印偶数。我对此感到非常困惑。我希望它能按顺序输出奇数和偶数,就像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, "只羊")
    }
}
英文:

I just tried the following code, but the result seems a little strange. It prints odd numbers first, and then even numbers. I'm really confused about it. I had hoped it outputs odd number and even number one after another, just like 1, 2, 3, 4... . Who can help me?

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")
    }
}

答案1

得分: 6

很可能你只在运行一个CPU线程。所以它会先运行第一个goroutine,然后再运行第二个。如果你告诉Go可以在多个线程上运行,那么只要操作系统有空闲的CPU时间,两个goroutine就可以同时运行。你可以在运行二进制文件之前设置GOMAXPROCS=2来演示这一点。或者你可以尝试在sheep函数中添加一个runtime.Gosched()调用,看看是否会触发运行时允许其他goroutine运行。

总的来说,最好不要假设两个goroutine之间的操作顺序,除非你使用sync.Mutex指定了特定的同步点,或者在它们之间通过通道进行通信。

英文:

More than likely you are only running with one cpu thread. so it runs the first goroutine and then the second. If you tell go it can run on multiple threads then both will be able to run simultaneously provided the os has spare time on a cpu to do so. You can demonstrate this by setting GOMAXPROCS=2 before running your binary. Or you could try adding a runtime.Gosched() call in your sheep function and see if that triggers the runtime to allow the other goroutine to run.

In general though it's better not to assume ordering semantics between operations in two goroutines unless you specify specific synchronization points using a sync.Mutex or communicating between them on channels.

答案2

得分: 3

Unsynchronized goroutines execute in a completely undefined order. If you want to print out something like

1 只羊
2 只羊
3 只羊
....

in that exact order, then goroutines are the wrong way to do it. Concurrency works well when you don't care so much about the order in which things occur.

You could impose an order in your program through synchronization (locking a mutex around the fmt.Println calls or using a channel), but it's pointless since you could more easily just write code that uses a single goroutine.

英文:

Unsynchronized goroutines execute in a completely undefined order. If you want to print out something like

1 sheeps
2 sheeps
3 sheeps
....

in that exact order, then goroutines are the wrong way to do it. Concurrency works well when you don't care so much about the order in which things occur.

You could impose an order in your program through synchronization (locking a mutex around the fmt.Println calls or using a channel), but it's pointless since you could more easily just write code that uses a single goroutine.

huangapple
  • 本文由 发表于 2012年6月26日 23:54:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/11211237.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定