Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 去阻止其他人_Go_Channel_Goroutine - Fatal编程技术网

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

下面的代码将永远运行,而不是在开始后一秒钟停止。 带有无限循环的go例程似乎阻止另一个发送到超时通道。这正常吗

 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)也是如此。