为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这个程序会在我的系统上终止而不是在操场上?

为什么这个程序会在我的系统上终止而不是在操场上?

Go
婷婷同学_ 2021-07-08 18:02:24
考虑这个程序:package mainimport "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上终止?我的程序的终止是否依赖于未定义的行为?
查看完整描述

3 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

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

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

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

竞赛检测器也可能会报告此问题。你真的不应该期望这会起作用。如果你想要一个,sync.WaitGroup你应该只使用一个,因为它可以跨线程正确协调。


查看完整回答
反对 回复 2021-07-12
?
DIEA

TA贡献1820条经验 获得超2个赞

Go Playground 使用了一种特殊的实现,time.Sleep旨在防止单个程序垄断网站的后端资源。

正如这篇关于如何实现Playground 的文章中所述,调用 time.Sleep() 的 goroutine 被置于睡眠状态。操场后端等待直到所有其他 goroutine 被阻塞(否则会出现死锁),然后以最短的时间唤醒 goroutine。

在您的程序中,您有两个 goroutine:一个主要的,一个调用time.Sleep. 由于主 goroutine 永远不会阻塞,因此time.Sleep调用永远不会返回。程序继续运行,直到超过分配给它的 CPU 时间,然后终止。


查看完整回答
反对 回复 2021-07-12
  • 3 回答
  • 0 关注
  • 219 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信