Go 使用vs进行无限循环而没有时间。Sleep()
我有一个goroutine可以无限播放一些音频Go 使用vs进行无限循环而没有时间。Sleep(),go,goroutine,Go,Goroutine,我有一个goroutine可以无限播放一些音频play()。为了使play()保持活动状态,我让调用函数在之后运行一个无限for循环 出乎意料的是,一个赤裸裸的循环似乎不能让函数无限发挥作用,我不知道为什么。但是,如果我在for循环的主体中添加一个简单的time.Sleep(time.Second),它似乎无限运行。你知道为什么吗 要可视化: func PlaysForAFewSeconds() { go play() for { } } ^播放几秒钟,但从不爆发 fu
play()
。为了使play()
保持活动状态,我让调用函数在之后运行一个无限for循环
出乎意料的是,一个赤裸裸的循环似乎不能让函数无限发挥作用,我不知道为什么。但是,如果我在for循环的主体中添加一个简单的time.Sleep(time.Second)
,它似乎无限运行。你知道为什么吗
要可视化:
func PlaysForAFewSeconds() {
go play()
for {
}
}
^播放几秒钟,但从不爆发
func PlaysForever() {
go play()
for {
time.Sleep(time.Second)
}
}
^永远演奏
我猜这与play()
的实现方式有关,但我希望这是一个足够常见的问题,有人能认识到这种症状。
谢谢。为{}生成的程序集是
jmp self
,其中self
是jmp
指令的位置。换句话说,CPU将尽可能快地运行jmp
指令。CPU每秒可以运行n条指令,不管这是无用的jmp
指令还是实际有用的指令
这被称为“忙等待”或“旋转锁”,这种行为并不特定于Go。大多数(所有?)编程语言的行为都是这样的
此类环路有一些用途,但在Go中,它们通常可以用通道代替:
// Simulate a function that takes 1s to complete.
func play(ch chan struct{}) {
fmt.Println("play")
time.Sleep(1 * time.Second)
ch <- struct{}{}
}
func PlaysForAFewSeconds() {
wait := make(chan struct{})
go play(wait)
<-wait
}
func PlaysForever() {
wait := make(chan struct{})
for {
go play(wait)
<-wait
}
}
//模拟一个需要1s才能完成的函数。
func play(ch chan结构{}){
fmt.Println(“播放”)
时间。睡眠(1*时间。秒)
ch为{}执行的程序集
生成的是jmp-self
,其中self
是jmp
指令的位置。换句话说,CPU将尽可能快地运行jmp
指令。CPU每秒可以运行n条指令,这是无用的jmp
指令还是实际有用的指令并不重要行动
这被称为“忙等待”或“旋转锁”,这种行为并不特定于Go。大多数(所有?)编程语言的行为都是这样的
此类环路有一些用途,但在Go中,它们通常可以用通道代替:
// Simulate a function that takes 1s to complete.
func play(ch chan struct{}) {
fmt.Println("play")
time.Sleep(1 * time.Second)
ch <- struct{}{}
}
func PlaysForAFewSeconds() {
wait := make(chan struct{})
go play(wait)
<-wait
}
func PlaysForever() {
wait := make(chan struct{})
for {
go play(wait)
<-wait
}
}
//模拟一个需要1s才能完成的函数。
func play(ch chan结构{}){
fmt.Println(“播放”)
时间。睡眠(1*时间。秒)
ch“为了保持play()的活动性,我让调用函数在之后运行一个无限for循环。”---这显然是错误的。启动goroutine后,它与调用它的代码没有任何连接。任何类型的循环都没有任何意义。如果play()
是阻塞,只是在没有goroutines的情况下运行它。我同意这是一个糟糕的代码,但它没有提供任何关于goroutine根据for-loop主体的不同行为的见解。有多少cpu可用于进程?使用什么go版本?是否在任何地方手动设置runtime.GOMAXPROCS
?4个cpu,而不是m正在使用runtime.GOMAXPROCS。繁忙循环总是一个编程错误。即使调度程序可能会中断它,它也没有用,并且会浪费cpu。请不要这样做。“为了保持play()活动,我让调用函数在之后运行无限for循环。”---这是完全错误的。启动goroutine后,它与调用它的代码没有任何连接。任何类型的循环都没有意义。如果play()
是阻塞,只是在没有goroutines的情况下运行它。我同意这是一个糟糕的代码,但它没有提供任何关于goroutine根据for-loop主体的不同行为的见解。有多少cpu可用于进程?使用什么go版本?是否在任何地方手动设置runtime.GOMAXPROCS
?4个cpu,而不是m正在使用runtime.GOMAXPROCS。繁忙的循环总是一个编程错误。即使调度程序可以中断它,它也没有用,并且浪费了cpu。只是不要这样做。我相信最初的问题是关于“它到底为什么会发生”。一个有用的“繁忙等待”或“旋转锁”实际上是在检查一些条件。空的jmp self
没有真正的用途。我相信最初的问题是关于“它到底为什么会发生”。有用的“忙等待”或“旋转锁”实际上是在检查一些条件。空的jmp self
没有真正的用途。