Skip to content

Instantly share code, notes, and snippets.

@vagra
Last active February 10, 2023 08:47
Show Gist options
  • Save vagra/a7560dc5321b78aa90e985134283bb45 to your computer and use it in GitHub Desktop.
Save vagra/a7560dc5321b78aa90e985134283bb45 to your computer and use it in GitHub Desktop.
mutiple goroutines: main -> an inputer -> many worker -> an outputer -> main.
package main
import (
"context"
"fmt"
"sync"
"time"
)
func worker(wg *sync.WaitGroup, ctx context.Context, i int, ci <-chan int, co chan<- string) {
wg.Add(1)
defer wg.Done()
count := 0
for {
select {
case <-ctx.Done():
fmt.Printf("worker %d : stop.\n", i)
return
case val := <-ci:
count++
if val < 0 {
fmt.Printf("worker %d <- inChan: numbers finished.\n", i)
fmt.Printf("worker %d -> outChan: numbers finished.\n", i)
co <- "end"
} else {
co <- fmt.Sprintf("worcker %d count %d val %d", i, count, val)
}
default:
time.Sleep(time.Millisecond * 1)
}
}
}
func inputer(wg *sync.WaitGroup, ctx context.Context, ci chan<- int, cn <-chan int) {
wg.Add(1)
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Println("inputer: stop.")
return
case num := <-cn:
if num < 0 {
fmt.Println("inputer <- numChan: numbers finished.")
fmt.Println("inputer -> inChan: numbers finished.")
ci <- -1
} else {
for i := 0; i < num; i++ {
ci <- i
}
}
default:
fmt.Println("inputer: waiting for signal...")
time.Sleep(time.Millisecond * 500)
}
}
}
func outputer(wg *sync.WaitGroup, ctx context.Context, co <-chan string, ce chan<- bool) {
wg.Add(1)
defer wg.Done()
i := 0
for {
select {
case <-ctx.Done():
fmt.Println("outputer: stop.")
return
case msg := <-co:
fmt.Println("outputer <- outChain: ", i, msg)
i++
if msg == "end" {
fmt.Println("outputer -> endChain: numbers finished.")
ce <- true
}
default:
fmt.Println("outputer: waiting for signal...")
time.Sleep(time.Millisecond * 500)
}
}
}
func main() {
var wg sync.WaitGroup
inChan := make(chan int, 100)
outChan := make(chan string, 100)
numChan := make(chan int)
endChan := make(chan bool)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
for i := 0; i < 5; i++ {
go worker(&wg, ctx, i, inChan, outChan)
}
go inputer(&wg, ctx, inChan, numChan)
go outputer(&wg, ctx, outChan, endChan)
numChan <- 50
numChan <- 20
numChan <- 10
println("main -> numChan: numbers finished.")
numChan <- -1
end := <-endChan
if end {
println("main <- endChan: numbers finished.")
println("main -> ctx: everyone stop!")
cancel()
}
wg.Wait()
}
@vagra
Copy link
Author

vagra commented Feb 10, 2023

outputer: waiting for signal...
inputer: waiting for signal...
inputer: waiting for signal...
outputer <- outChain:  0 worcker 2 count 1 val 0
outputer <- outChain:  1 worcker 2 count 2 val 1
outputer <- outChain:  2 worcker 2 count 3 val 2
outputer <- outChain:  3 worcker 2 count 4 val 3
outputer <- outChain:  4 worcker 2 count 5 val 4
outputer <- outChain:  5 worcker 2 count 6 val 5
outputer <- outChain:  6 worcker 2 count 7 val 6
outputer <- outChain:  7 worcker 2 count 8 val 7
outputer <- outChain:  8 worcker 2 count 9 val 8
outputer <- outChain:  9 worcker 2 count 10 val 9
outputer <- outChain:  10 worcker 2 count 11 val 10
outputer <- outChain:  11 worcker 2 count 12 val 11
outputer <- outChain:  12 worcker 2 count 13 val 12
outputer <- outChain:  13 worcker 2 count 14 val 13
outputer <- outChain:  14 worcker 2 count 15 val 14
outputer <- outChain:  15 worcker 2 count 16 val 15
outputer <- outChain:  16 worcker 2 count 17 val 16
outputer <- outChain:  17 worcker 2 count 18 val 17
outputer <- outChain:  18 worcker 2 count 19 val 18
outputer <- outChain:  19 worcker 2 count 20 val 19
outputer <- outChain:  20 worcker 2 count 21 val 20
outputer <- outChain:  21 worcker 2 count 22 val 21
outputer <- outChain:  22 worcker 2 count 23 val 22
outputer <- outChain:  23 worcker 2 count 24 val 23
outputer <- outChain:  24 worcker 2 count 25 val 24
outputer <- outChain:  25 worcker 2 count 26 val 25
outputer <- outChain:  26 worcker 2 count 27 val 26
outputer <- outChain:  27 worcker 2 count 28 val 27
outputer <- outChain:  28 worcker 2 count 29 val 28
outputer <- outChain:  29 worcker 2 count 30 val 29
outputer <- outChain:  30 worcker 2 count 31 val 30
outputer <- outChain:  31 worcker 2 count 32 val 31
outputer <- outChain:  32 worcker 2 count 33 val 32
outputer <- outChain:  33 worcker 2 count 34 val 33
outputer <- outChain:  34 worcker 2 count 35 val 34
outputer <- outChain:  35 worcker 2 count 36 val 35
outputer <- outChain:  36 worcker 2 count 37 val 36
outputer <- outChain:  37 worcker 2 count 38 val 37
outputer <- outChain:  38 worcker 2 count 39 val 38
outputer <- outChain:  39 worcker 2 count 40 val 39
outputer <- outChain:  40 worcker 2 count 41 val 40
outputer <- outChain:  41 worcker 2 count 42 val 41
outputer <- outChain:  42 worcker 2 count 43 val 42
outputer <- outChain:  43 worcker 2 count 44 val 43
outputer <- outChain:  44 worcker 2 count 45 val 44
outputer <- outChain:  45 worcker 2 count 46 val 45
outputer <- outChain:  46 worcker 2 count 47 val 46
outputer <- outChain:  47 worcker 2 count 48 val 47
outputer <- outChain:  48 worcker 2 count 49 val 48
outputer <- outChain:  49 worcker 2 count 50 val 49
outputer <- outChain:  50 worcker 4 count 1 val 0
outputer <- outChain:  51 worcker 0 count 1 val 1
outputer <- outChain:  52 worcker 0 count 2 val 3
outputer <- outChain:  53 worcker 0 count 3 val 4
outputer <- outChain:  54 worcker 0 count 4 val 5
outputer <- outChain:  55 worcker 0 count 5 val 6
outputer <- outChain:  56 worcker 4 count 2 val 2
outputer <- outChain:  57 worcker 0 count 6 val 7
outputer <- outChain:  58 worcker 4 count 3 val 8
outputer <- outChain:  59 worcker 0 count 7 val 9
outputer <- outChain:  60 worcker 4 count 4 val 10
outputer <- outChain:  61 worcker 0 count 8 val 11
outputer <- outChain:  62 worcker 4 count 5 val 12
outputer <- outChain:  63 worcker 0 count 9 val 13
outputer <- outChain:  64 worcker 4 count 6 val 14
outputer <- outChain:  65 worcker 0 count 10 val 15
outputer <- outChain:  66 worcker 4 count 7 val 16
outputer <- outChain:  67 worcker 0 count 11 val 17
outputer <- outChain:  68 worcker 4 count 8 val 18
outputer <- outChain:  69 worcker 0 count 12 val 19
outputer: waiting for signal...
inputer: waiting for signal...
main -> numChan: numbers finished.
outputer <- outChain:  70 worcker 0 count 13 val 0
outputer <- outChain:  71 worcker 0 count 14 val 1
outputer <- outChain:  72 worcker 0 count 15 val 2
outputer <- outChain:  73 worcker 0 count 16 val 3
outputer <- outChain:  74 worcker 0 count 17 val 4
outputer <- outChain:  75 worcker 0 count 18 val 5
outputer <- outChain:  76 worcker 0 count 19 val 6
outputer <- outChain:  77 worcker 0 count 20 val 7
outputer <- outChain:  78 worcker 0 count 21 val 8
outputer <- outChain:  79 worcker 0 count 22 val 9
outputer: waiting for signal...
inputer <- numChan: numbers finished.
inputer -> inChan: numbers finished.
inputer: waiting for signal...
worker 4 <- inChan: numbers finished.
worker 4 -> outChan: numbers finished.
outputer <- outChain:  80 end
outputer -> endChain: numbers finished.
outputer: waiting for signal...
main <- endChan: numbers finished.
main -> ctx: everyone stop!
worker 3 : stop.
worker 0 : stop.
worker 4 : stop.
worker 1 : stop.
worker 2 : stop.
inputer: stop.
outputer: stop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment