closing channel quits multiple go routines?

Issue

Given this code:

package main

import (
  "fmt"
  "time"
)

func first(quit chan error) {
  fmt.Println("1")
  for {
    select {
    case <-quit:
      fmt.Println("first quits")
      return
    default:
      time.Sleep(20 * time.Millisecond)
    }
  }
}

func second(quit chan error) {
  fmt.Println("2")
  for {
    select {
    case <-quit:
      fmt.Println("second quits")
      return
    default:
      time.Sleep(20 * time.Millisecond)
    }
  }
}

func main() {
  quit := make(chan error)
  go first(quit)
  go second(quit)
  //something happens here, let's just simulate with a sleep
  time.Sleep(500 * time.Millisecond)
  close(quit)
  time.Sleep(500 * time.Millisecond)
}

It seems that closing a channel correctly terminates two independent go routines. I thought channels were 1:1 communication paths, I was first trying to write an error into the quit channel but then only one of the go routines would be reading it. So I was reading all sorts of fan-out strategies until it occurred to me that closing the channel might just work.

Is closing the channel in this way the correct method to terminate independent go routines?

Solution

Reading from a closed channel always succeeds. Because of this, closing a channel is usually used to broadcast all goroutines that read from that channel that something has happened (timeout, cancel request, etc).

To answer your question: test, closing a channel is a correct way to let all goroutines know that it is time to terminate. That is what context.Context does when it is canceled.

Answered By – Burak Serdar

Answer Checked By – Jay B. (GoLangFix Admin)

Leave a Reply

Your email address will not be published.