Skip to content

Instantly share code, notes, and snippets.

@debedb
Last active November 25, 2022 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save debedb/8288783efcc70a0dd3f2159ef9c730c6 to your computer and use it in GitHub Desktop.
Save debedb/8288783efcc70a0dd3f2159ef9c730c6 to your computer and use it in GitHub Desktop.
Go: Goroutines and channels
package main
import (
"fmt"
"strconv"
"sync"
"sync/atomic"
)
// No deadlock on all sleeping, etc.
// Careful use of WaitGroups and closing of channel
func producersConsumers() {
receivedTotal := 0
receivedTotalAtomic := atomic.Int32{}
var recvWg sync.WaitGroup
var sendWg sync.WaitGroup
ch := make(chan string, 5)
recvSimple := func(s string) {
defer recvWg.Done()
for {
msg, open := <-ch
if !open {
break
}
receivedTotal++
receivedTotalAtomic.Add(1)
fmt.Printf("Receiver %s received %s\n", s, msg)
}
}
go recvSimple("One")
go recvSimple("Two")
recvWg.Add(2)
recvRange := func(s string) {
defer recvWg.Done()
for msg := range ch {
fmt.Printf("Receiver %s received %s\n", s, msg)
}
}
go recvRange("Three")
go recvRange("Four")
recvWg.Add(2)
send := func(name string) {
defer sendWg.Done()
for i := 0; i < 1000; i++ {
s := name + " " + strconv.Itoa(i)
//fmt.Printf("Sending %s\n", s)
ch <- s
}
fmt.Printf("Sender %s exiting\n", name)
}
go send("Uno")
go send("Due")
go send("Tre")
sendWg.Add(3)
sendWg.Wait()
close(ch)
recvWg.Wait()
fmt.Printf("Processed %d (not necessarily %d!) messages\n", receivedTotalAtomic.Load(), receivedTotal)
}
func pingPong() {
cnt := 0
ch := make(chan string)
var wg sync.WaitGroup
f := func(me string) {
defer wg.Done()
for {
msg, hasMore := <-ch
if !hasMore {
fmt.Println(me, ": Good game")
break
}
fmt.Println(msg)
cnt += 1
ch <- me
}
}
go f("Pong")
go f("Ping")
wg.Add(2)
ch <- "Start!"
for cnt < 10 {
// Wait (we're sleeping above)
}
s := <-ch
fmt.Println("Ok, this was the last ", s)
close(ch)
wg.Wait()
}
func main() {
producersConsumers()
fmt.Println("*****************************************")
pingPong()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment