Skip to content

Instantly share code, notes, and snippets.

@abitofhelp
Last active July 28, 2018 01:33
Show Gist options
  • Save abitofhelp/814549a9a3ebd42dde27a3cff5e65883 to your computer and use it in GitHub Desktop.
Save abitofhelp/814549a9a3ebd42dde27a3cff5e65883 to your computer and use it in GitHub Desktop.
This gist shows the use of a buffered channel with a single sender and multiple receivers.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018 A Bit of Help, Inc. - All Rights Reserved, Worldwide.
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Package main is the entry point for the application
// and is responsible for configuring the environment.
package main
import (
"fmt"
"sync"
"time"
)
// Function main is the entry point for the application and is responsible
// for configuring its environment.
func main() {
// Variable wg is main's WaitGroup, which detects when all of the
// goroutines that were launched have completed.
var wg sync.WaitGroup
// Start our timer...
start := time.Now()
// Doing something...
doIt(&wg)
// Wait here until all goroutines have completed their work.
wg.Wait()
// Show the duration.
fmt.Printf("Elapsed: %s", time.Since(start))
}
// Function receiver1 will loop continuously trying to receive a value from the channel.
// Parameter ch is a unidirectional channel for reading integer values.
// Remarks are that the way that the value is retrieved can be simplified using a
// for loop over a range, as in receiver2. Both methods work properly, but receiver2
// is more concise and easily understood.
func receiver1(ch <-chan int) {
for {
val, ok := <-ch
if !ok {
return
}
fmt.Println("Receiver1: ", val)
}
}
// Function receiver2 uses a for loop over a range to receive a value from the channel.
// Parameter ch is a unidirectional channel for reading integer values.
func receiver2(ch <-chan int) {
for val := range ch {
fmt.Println("Receiver2: ", val)
}
}
// Function sender places 10000 integers into a unidirectional channel for sending integer
// values.
// Parameter ch is a unidirectional channel for reading integer values.
func sender(ch chan<- int) {
for i := 1; i <= 10000; i++ {
fmt.Println("Sending: ", i)
ch <- i
}
// Close the channel there are no more values to send...
// It signals the receivers that there are no more values,
// so when the channel is empty, they can return and the application
// can terminate.
close(ch)
}
// Function doIt does the work. It creates the channel,
// launches the goroutines and returns to main().
// Please note that a single sender is broadcasting values to
// two receivers over the channel.
func doIt(wg *sync.WaitGroup) {
// Create the bidirectional channel for communications between
// the goroutines.
ch := make(chan int, 100)
// Launch receiver1 and set up the WaitGroup to account for it.
wg.Add(1)
go func() {
defer wg.Done()
receiver1(ch)
}()
// Launch receiver2 and set up the WaitGroup to account for it.
wg.Add(1)
go func() {
defer wg.Done()
receiver2(ch)
}()
// Launch sender and set up the WaitGroup to account for it.
wg.Add(1)
go func() {
defer wg.Done()
sender(ch)
}()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment