一尘不染

为什么该程序在我的系统上终止而不在操场上终止?

go

考虑以下程序:

package main

import "fmt"
import "time"
import "runtime"

func main() {

    x := 0

    go func() {
        time.Sleep(500 * time.Millisecond)
        x = 1
    }()

    for x == 0 {
        runtime.Gosched()
    }

    fmt.Println("it works!")
}

为什么它在本地终止而不在Playground终止?我的程序终止是否依赖未定义的行为?


阅读 244

收藏
2020-07-02

共1个答案

一尘不染

该代码不能提供太多保证。它几乎完全依赖于围绕未定义行为的实现细节。

在大多数多线程系统中,不能保证一个线程中的更改不会出现障碍。您有一个goroutine,可以在另一个处理器上运行,总共将一个值写入一个没有人保证读取的变量。

for x == 0 {可以很容易地重写for {,因为从未有一个保证该变量的任何变化可能是可见的。

种族探测器也可能会报告此问题。您真的不应该期望此方法有效。如果您想要一个,sync.WaitGroup您应该只使用一个,因为它可以正确地跨线程协调。

2020-07-02