多个 goroutine 中的 Scanf 给出了意想不到的结果

Var*_*n V 5 go

我只是在 golang 中做实验。我遇到了一个有趣的结果。这是我的代码。

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    var str1, str2 string
    wg.Add(2)
    go func() {
        fmt.Scanf("%s", &str1)
        wg.Done()
    }()
    go func() {
        fmt.Scanf("%s", &str2)
        wg.Done()
    }()
    wg.Wait()
    fmt.Printf("%s %s\n", str1, str2)
}
Run Code Online (Sandbox Code Playgroud)

我给出了以下输入。

beat
it
Run Code Online (Sandbox Code Playgroud)

我期待结果是

it beat
Run Code Online (Sandbox Code Playgroud)

或者

beat it
Run Code Online (Sandbox Code Playgroud)

但我得到了。

eat bit
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我弄清楚为什么会这样吗?

Den*_*ret 4

fmt.Scanf不是原子操作。这是实现:http://golang.org/src/pkg/fmt/scan.go#L1115

没有信号量,没有什么可以阻止两个并行执行。所以发生的情况很简单,执行实际上是并行的,并且由于没有缓冲,任何字节读取都是 IO 操作,因此是 go 调度程序更改 goroutine 的最佳时机。