Last active
February 10, 2023 08:47
-
-
Save vagra/a7560dc5321b78aa90e985134283bb45 to your computer and use it in GitHub Desktop.
mutiple goroutines: main -> an inputer -> many worker -> an outputer -> main.
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
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() | |
} |
Author
vagra
commented
Feb 10, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment