为什么此代码未定义行为? [英] Why is this code Undefined Behavior?

查看:157
本文介绍了为什么此代码未定义行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  var x int 
完成:= false
去func(){x = f(...); done = true}
完成== false {}

这是一个Go代码片。我的恶魔告诉我这是UB代码。为什么?

解决方案

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


Go Memory Model不保证在 main 程序中会观察到在goroutine中写入x的值。

一个类似错误的程序作为示例在<一个href =http://golang.org/ref/mem#tmp_5 =nofollow noreferrer>去例行破坏。
Go Memory模型还特别呼叫忙等待没有同步作为本节中的一个不正确的习语。


(在您的情况下,不能保证写入 b
$ b $ p> >在这里,您需要在goroutine中进行某种同步以保证 done <= code>在 main 中循环的迭代之前发生。 / p>

(Go中不存在)应该被替换为,例如,您阻止的频道(等待沟通)

pre $ 为{
<-c // 2
}

基于频道( c:= make(chan bool) main 中创建,并在goroutine中关闭( close(c))。






同步包提供了其他方法来等待gorountine在退出main之前结束。

参见Golang示例

  var w sync.WaitGroup 
w.Add(1)
go func(){
//做某事
w.Done()
}
w.Wait()


  var x int
  done := false
  go func() { x = f(...); done = true }
  while done == false { }

This is a Go code piece. My fiend told me this is UB code. Why?

As explained in "Why does this program terminate on my system but not on playground?"

The Go Memory Model does not guarantee that the value written to x in the goroutine will ever be observed by the main program.
A similarly erroneous program is given as an example in the section on go routine destruction.
The Go Memory Model also specifically calls out busy waiting without synchronization as an incorrect idiom in this section.

(in your case, there is no guarantee that the value written to done in the goroutine will ever be observed by the main program)

Here, You need to do some kind of synchronization in the goroutine in order to guarantee that done=true happens before one of the iterations of the for loop in main.

The "while" (non-existent in Go) should be replaced by, for instance, a channel you block on (waiting for a communication)

for {
    <-c // 2
}

Based on a channel (c := make(chan bool)) created in main, and closed (close(c)) in the goroutine.


The sync package provides other means to wait for a gorountine to end before exiting main.

See for instance Golang Example Wait until all the background goroutine finish:

var w sync.WaitGroup
w.Add(1)
go func() {
    // do something
    w.Done()
}
w.Wait()

这篇关于为什么此代码未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆