停止阻塞的 goroutine

Stop a blocking goroutine

如何杀死正在阻塞的 goroutine。一个想法是从主机函数返回将是一个解决方案,但我不确定这是否会杀死 goroutine。

func myFunc() int {
   c := make(<-chan int)
   go func(){
      for i := range c {
      // do stuff
      }
   }()
   return 0 // does this kills the inner goroutine?
}

有更好的方案吗?例如,像这样的东西会很好,但由于它的阻塞不会:

func myFunc() int {
   c := make(<-chan int)
   closeChan := make(chan int)
   go func() {
      select {
      case close := <-closeChan:
         return 0
      default:
         for i := range c {
            // do stuff
         }
      }
   }()
   closeChan<-0
   // other stuff
}

你不能从外部杀死一个 goroutine——你甚至不能引用一个特定的 goroutine;您也不能中止阻塞操作。但是,您可以将 for 移到外面:

go func() {
   for  {
       select {
       case close := <-closeChan:
          return 0
       case i,ok := <-c:
         // do stuff
         if !ok {
             // channel is closed & empty
             return 0
         }
       }
   }
}()

这将永远循环,每次迭代都会在两个通道上等待消息;谁先收到消息,谁就被处理,然后循环重复。这是 Go 中非常常见的模式。