Last active
November 25, 2022 21:05
-
-
Save debedb/8288783efcc70a0dd3f2159ef9c730c6 to your computer and use it in GitHub Desktop.
Go: Goroutines and channels
This file contains hidden or 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
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