Stop a blocking goroutine

Issue

How can I kill a goroutine which is blocking. An idea is that returning from the host function would be a solution but I’m not sure if this kills the goroutine or not.

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

Is there a more nice solution? For example it would be nice that something like this work but because of the blocking for it doesn’t:

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
}

Solution

You can’t kill a goroutine from outside – you can’t even reference a specific goroutine; nor can you abort a blocking operation. You can, however, move the for to the outside:

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

This will loop forever, and each iteration it will wait for a message on both channels; whichever gets a message first will be processed, then the loop repeats. This is a very common pattern in Go.

Answered By – Adrian

Answer Checked By – David Marino (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.