Last active
July 28, 2018 01:33
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// 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