Channels in Go


Do not communicate by sharing memory; instead, share memory by communicating.

Channels are for orchestration, mutexes are for serialization.

Go Proverbs – Rob Pike

Yesterday I wrote my first project ((It’s URL shorterer, a project which I write in every new programming language I learn.)) in Go which does not use traditional locks when dealing with shared data in concurrent programs but instead uses channels. Although I admit it’s little more complex than mutexes the end result is more readable and decoupled code. It also made me agreeing with that second quote above.

Examples of channel use cases which I used:

  • blocking the execution till some operation is completed. With <- done goroutine waits till some value is put into the channel done from some other goroutine. One cool way to utilize this is faking time.Sleep in tests.
  • time.After(5*time.Second) returns a channel which receives a value after every 5 seconds. Which means we can execute some logic every 5 seconds.
  • catching the signals and handling them (this needs to be done in separate goroutine otherwise whole program will be blocked).
    go func() {
      signalChan := make(chan os.Signal)
      signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
      <-signalChan // this blocks current goroutine until sigint or sigterm signals 
      fmt.Println("Exiting the program and doing some cleanup...")
      // ...
      os.Exit(0)
    }()