为了解决我对goroutine的一些误解,我去了Go游乐场并运行了以下代码:
package main
import (
"fmt"
)
func other(done chan bool) {
done <- true
go func() {
for {
fmt.Println("Here")
}
}()
}
func main() {
fmt.Println("Hello, playground")
done := make(chan bool)
go other(done)
<-done
fmt.Println("Finished.")
}
如我所料,Go操场出现了一个错误: 过程花费了太长时间 。
这似乎暗示在其中创建的goroutine other
永远运行。
但是,当我在自己的机器上运行相同的代码时,几乎立即获得以下输出:
Hello, playground.
Finished.
这似乎暗示other
主goroutine完成时,其中的goroutine将退出。 这是真的?
还是主goroutine完成,而其他goroutine继续在后台运行?
在Go
Playground上,GOMAXPROCS是1
(证明)。
这意味着一次执行一个goroutine,并且如果该goroutine没有阻塞,则不会强制调度程序切换到其他goroutine。
您的代码(像每个Go应用程序一样)以执行main()
函数的goroutine(主goroutine)开始。它启动另一个执行该other()
功能的goroutine
,然后从done
通道接收-阻塞。因此,调度程序必须切换到另一个goroutine(执行other()
功能)。
在other()
html" target="_blank">函数中,当您在done
通道上发送值时,这将使当前(other()
)和main
goroutine可运行。调度选择继续运行other()
,并且因为GOMAXPROCS=1
,main()
没有继续。现在other()
启动另一个执行无限循环的goroutine。调度程序选择执行此goroutine,这将永远花费到阻塞状态,因此main()
不会继续。
然后,Go Playground沙箱的超时就可以解决:
过程花了太长时间
请注意, Go Memory Model
仅保证某些事件先于其他事件发生,而不能保证如何执行2个并发goroutine。这使得输出不确定。
您不要质疑任何不违反Go Memory
Model的执行顺序。如果您希望执行达到代码中的某些点(执行某些语句),则需要显式同步(您需要同步goroutine)。
另请注意,Go
Playground上的输出已缓存,因此如果再次运行该应用程序,则不会再次运行该应用程序,而是会立即显示已缓存的输出。如果您更改了代码中的任何内容(例如,插入空格或注释),然后再次运行它,它将被编译并再次运行。您会注意到响应时间增加了。使用当前版本(Go
1.6),您每次都会看到相同的输出。
在本地运行它时,很有可能GOMAXPROCS
会大于1
默认值,因为它默认为可用的CPU核心数(从Go
1.5开始)。因此,是否有执行无穷循环的goroutine无关紧要,另一个goroutine将同时执行,即main()
,当main()
返回时,程序终止;它不会等待其他非main
例程完成(请参见规范:程序执行)。
另请注意,即使您将设置GOMAXPROCS
为1
,您的应用也很可能会在“很短的时间内”退出,因为调度程序的实现将切换到其他goroutine,而不仅仅是永久执行无限循环(但是,如上所述,这是不确定的)。然后,它将成为main()
goroutine,因此当main()
完成并返回时,您的应用程序终止。
如前所述,默认情况下GOMAXPROCS
位于1
Go Playground上。但是,可以将其设置为更高的值,例如:
runtime.GOMAXPROCS(2)
没有显式同步,执行仍然是不确定的,但是您会观察到不同的执行顺序和终止,而不会发生超时:
Hello, playground
Here
Here
Here
...
<Here is printed 996 times, then:>
Finished.
在Go Playground上尝试使用此变体。
问题内容: 今天,我的一个好朋友问我最新的Go语言和Cython之间的主要区别是什么,后者是Python的一组C扩展。我对Python的了解不多,有人可以告诉我为什么Go比Cython更好/更差吗? 问题答案: Cython并不是传统意义上的语言。它是构建Python扩展程序的预处理器,该扩展程序采用类似Python的语法(实际上,他们力求完全兼容Python)并生成C代码(使用Python C
问题内容: 很快就有两个相等运算符:double equals( )和Triple equals( ),两者之间有什么区别? 问题答案: 简而言之: 操作员检查其实例值是否相等, 操作员检查引用是否指向同一实例, 长答案: 类是引用类型,可能有多个常量和变量在幕后引用类的同一单个实例。类引用保留在运行时堆栈(RTS)中,其实例保留在内存的堆区域中。当您控制平等时, 这意味着它们的实例是否彼此相等。
和操作符之间有什么区别,它们的用例是什么?他们似乎都在等待一项任务?
我编写了一个简单的脚本,它接受任意数量的参数来演示< code>$@和< code>$*之间的区别: 在我做的 CLI 上 这就是打印出来的 因为它们是相同的,这是否意味着等于?还是我遗漏了一点?
本文向大家介绍成本差异和进度差异之间的差异,包括了成本差异和进度差异之间的差异的使用技巧和注意事项,需要的朋友参考一下 对于任何应用程序或专门用于任何项目,最关注的因素之一是在开发前和开发后阶段的预算管理和时间管理。因此,要评估任何项目的这两个主要因素,有很多方法,其中成本差异和进度差异是两个重要且主要的方法。 顾名思义,“成本差异”基于项目开发中花费的成本,而“进度差异”则基于相同开发中花费的时
我现在做了很多研究,以找出React Native项目、CRNA和世博会项目之间的确切区别和取舍。 我的主要指导是 但是,我仍然不明白,与使用本机代码的普通React本机项目相比,使用ExpoKit和本机代码有什么(不)优势,除了我不能在普通React本机项目中使用Expo API这一事实。 我知道,当我在世博会上启动一个项目时,我可以将其作为ExpoKit项目或React原生项目弹出。在这两种情