当前位置: 首页 > 面试题库 >

为什么此代码未定义行为?

郑浩博
2023-03-14
问题内容

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

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


问题答案:

Go Memory
Model不保证该main程序将始终遵守在goroutine中写入x的值。go常规销毁
部分中提供了一个类似的错误程序作为示例。
在本节中,Go内存模型还专门调出了没有同步的繁忙等待,这是不正确的习惯用法。

(在您的情况下,无法保证程序done会遵守在goroutine中写入的值main

在这里,您需要在goroutine中进行某种同步,以确保在in done=true中的for循环迭代之前发生main

while”(Go中不存在)应替换为例如您阻塞的通道(等待通信)

for {
    <-c // 2
}

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

同步包提供其他手段离开主之前等待一个gorountine到端。

例如查看Golang示例等待所有后台goroutine完成:

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


 类似资料:
  • 问题内容: 我有以下JavaScript代码: 我希望它应该输出以下输出: 但是,它打印以下内容: 为什么在第一次迭代后打印“未定义”?重要说明: 仅 当在JavaScript控制台中执行代码时,我 才会 看到这种行为。如果它是页面的一部分,则可以正常工作。 问题答案: 这是因为“ printCounter()”函数本身返回。那是控制台告诉您表达式的结果。 通过添加到末尾来更改“ printCou

  • 问题内容: 我编写了以下程序: 由于通道事件列表是一个缓冲通道,我想我应该获得100倍的输出“嘿!”,但是它只显示一次。我的错误在哪里? 问题答案: 更新(Go 1.2版或更高版本) 从Go 1.2开始,调度程序基于 抢先式多任务处理 原则。这意味着原始问题(以及下面提供的解决方案)中的问题不再相关。 从Go 1.2发行说明中 调度程序中的抢占 在以前的版本中,永远循环的goroutine可能会使

  • 问题内容: 在方法或类范围内,下面的行进行编译(带有警告): 在类范围中, 变量获取其默认值 ,以下给出“未定义引用”错误: 它不是第一个应该以相同的“未定义参考”错误结束吗?还是第二行应该编译?还是我缺少什么? 问题答案: tl; dr 对于 字段 ,是非法的,因为它是对的非法前向引用。您实际上可以通过编写来解决此问题,该文件可以毫无抱怨地进行编译。 对于 局部变量 ,是非法的,因为未在使用前进

  • 问题内容: 为什么这段代码不抛出?它在不使用方法的情况下修改了一段时间,这是唯一安全的删除方法。 如果将替换为,则会得到相同的结果。但是,如果我将列表更改为或只是得到了预期的异常。到底是怎么回事?我正在使用是否相关。 编辑 我找到了以下链接 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078 相关部分是 天真的解决方案是将协同修改

  • 问题内容: 我正在使用Vue.js创建一个组件。 当我引用中的任何所述的生命周期钩(,,等等)它的计算结果为: 我的计算属性内部也发生了同样的事情: 我收到以下错误: 未捕获的TypeError:无法读取未定义的属性“ bar” 为什么要在这些情况下进行评估? 问题答案: 这两个示例都使用arrow函数,该函数绑定到与Vue实例不同的上下文。 根据文档: 不要在实例属性或回调(例如)上使用箭头功能

  • 问题内容: 这是我的代码: 当运行它输出。我究竟做错了什么? 问题答案: 您正在调用一个没有隐式字符串表示形式的实际数组。 为了输出数组的内容,你可以使用,或功能或自定义输出,你可以使用,甚至是循环: