Go 去阻止其他人
下面的代码将永远运行,而不是在开始后一秒钟停止。 带有无限循环的go例程似乎阻止另一个发送到超时通道。这正常吗Go 去阻止其他人,go,channel,goroutine,Go,Channel,Goroutine,下面的代码将永远运行,而不是在开始后一秒钟停止。 带有无限循环的go例程似乎阻止另一个发送到超时通道。这正常吗 func main(){ timeout:=make(chan int) go func(){ time.SLeep(time.Second) timeout<-1 }() res:=make(chan int) go func(){ for{ } res<-1
func main(){
timeout:=make(chan int)
go func(){
time.SLeep(time.Second)
timeout<-1
}()
res:=make(chan int)
go func(){
for{
}
res<-1
}()
select{
case<-timeout:
fmt.Println("timeout")
case<-res:
fmt.Println("res")
}
}
func main(){
超时:=制造(成交量)
go func(){
时间。睡眠(时间。秒)
超时这是因为对于单个处理器,您的第二个goroutine将忙着等待(通过循环垄断处理器,从不让另一个goroutine运行)
例如,如果将time.Sleep(time.millis秒)
放在for循环中,它就会工作:
这是因为对于单个处理器,您的第二个goroutine将忙着等待(通过循环垄断处理器,从不让另一个goroutine运行)
例如,如果将time.Sleep(time.millis秒)
放在for循环中,它就会工作:
简短回答:是的
当前的实现在goroutine之间使用协作调度。这意味着一个goroutine必须将执行交给调度程序,以便另一个goroutine运行。将来有希望使用一个不受此限制的抢占式调度程序
当发生以下任何情况时(可能不是一个全面的列表),Goroutines将向调度器屈服:
- 无缓冲chan发送/接收
- 系统调用(包括文件/网络读写)
- 内存分配
- 调用time.Sleep()
- 调用runtime.Gosched()
最后一个允许您在处理器非常密集的循环中手动向调度程序屈服。我从未发现需要它,因为我使用的几乎所有东西都有足够的通信(通道或系统io),因此我的程序永远不会卡住
还有一个GOMAXPROCS,您可能会听到它是解决这个问题的一个解决方案。虽然它允许您的所有goroutine通过将它们放在不同的线程中来运行,但垃圾收集器最终会尝试运行并停止世界。当它停止世界时,不允许任何goroutine运行,如果高cpu goroutine永远不会产生,GC将停止永远阻止goroutines,但永远不要运行。简短回答:是
当前的实现在goroutine之间使用协作调度。这意味着一个goroutine必须将执行交给调度程序,以便另一个goroutine运行。将来有希望使用一个不受此限制的抢占式调度程序
当发生以下任何情况时(可能不是一个全面的列表),Goroutines将向调度器屈服:
- 无缓冲chan发送/接收
- 系统调用(包括文件/网络读写)
- 内存分配
- 调用time.Sleep()
- 调用runtime.Gosched()
最后一个允许您在处理器非常密集的循环中手动向调度程序屈服。我从未发现需要它,因为我使用的几乎所有东西都有足够的通信(通道或系统io),因此我的程序永远不会卡住
还有一个GOMAXPROCS,您可能会听到它是解决这个问题的一个解决方案。虽然它允许您的所有goroutine通过将它们放在不同的线程中来运行,但垃圾收集器最终会尝试运行并停止世界。当它停止世界时,不允许任何goroutine运行,如果高cpu goroutine永远不会产生,GC将停止永远阻止goroutines,但永远不要运行。这个SO q/a对此表示抱歉。这个SO q/a对此表示抱歉。Thx purkito。有一个很长的答案Thx purkito。有一个很长的答案很奇怪:没有操作系统支持(因此没有操作系统线程),如何实现抢占式调度程序?嗯,我认为在自定义虚拟机中实现某种抢占式多任务处理是可能的,但它可能只进行解释,因此速度非常慢。而且这显然是不可能的。从这一点判断:似乎计划有一个monitor OS线程来处理它。如果你知道调度程序是coope的话rative(我们是这样做的)确保程序协作并不困难。这对运行时实现者来说是一个相当大的好处,因为抢占式调度通常效率较低,因为需要保存的上下文无法优化。Transputer遵循协作原则,实现了难以置信的快速上下文切换时间(类似于过程调用开销)…现代Occam Pi编译器(来自肯特)也是如此。只是好奇:没有操作系统支持(因此没有操作系统线程),如何实现抢占式调度程序?嗯,我认为在自定义虚拟机中实现某种抢占式多任务处理是可能的,但它可能只进行解释,因此速度非常慢。而且这显然是不可能的。从这一点判断:似乎计划有一个monitor OS线程来处理它。如果你知道调度程序是coope的话rative(我们是这样做的)确保程序协作并不困难。这对运行时实现者来说是一个相当大的好处,因为抢占式调度通常效率较低,因为需要保存的上下文无法优化。Transputer遵循协作原则,实现了难以置信的快速上下文切换时间(类似于过程调用开销)…现代Occam Pi编译器(来自Kent)也是如此。