From 68ff6d5edde85c64393a2bac22cd822f8d27fbc5 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Mon, 13 May 2019 09:26:47 +0800 Subject: [PATCH] Add example29: handle multiple Go channel Signed-off-by: Bo-Yi Wu --- README.md | 1 + .../answer/main.go | 50 +++++++++++++++++++ example29-handle-multiple-channel/main.go | 22 ++++++++ 3 files changed, 73 insertions(+) create mode 100644 example29-handle-multiple-channel/answer/main.go create mode 100644 example29-handle-multiple-channel/main.go diff --git a/README.md b/README.md index 75813e1..70ee6fa 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Learning basic [Golang](https://golang.org/) in one day * [example25](./example25-traefik-golang-app-lets-encrypt): Running golang app using [traefik & Let's Encrypt & Docker](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/). * [example27](./example27-how-to-load-env): How to loads environment variables from `.env`. * [example28](./example28-webserver-with-gracefull-shutdown): Go webserver with gracefull shutdown. +* [example29](./example29-handle-multiple-channel): How to handle multiple Go channel? [1]:https://github.com/golang/lint [2]:https://golang.org/cmd/gofmt/ diff --git a/example29-handle-multiple-channel/answer/main.go b/example29-handle-multiple-channel/answer/main.go new file mode 100644 index 0000000..75ba368 --- /dev/null +++ b/example29-handle-multiple-channel/answer/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "errors" + "fmt" + "math/rand" + "sync" + "time" +) + +func main() { + outChan := make(chan int, 100) + errChan := make(chan error) + finishChan := make(chan struct{}) + wg := sync.WaitGroup{} + wg.Add(100) + for i := 0; i < 100; i++ { + go func(outChan chan<- int, errChan chan<- error, val int, wg *sync.WaitGroup) { + defer wg.Done() + time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond) + fmt.Println("finished job id:", val) + outChan <- val + if val == 60 { + errChan <- errors.New("error in 60") + } + + }(outChan, errChan, i, &wg) + } + + go func() { + wg.Wait() + fmt.Println("finish all job") + close(finishChan) + }() + +Loop: + for { + select { + case val := <-outChan: + fmt.Println("finished:", val) + case err := <-errChan: + fmt.Println("error:", err) + break Loop + case <-finishChan: + break Loop + case <-time.After(100000 * time.Millisecond): + break Loop + } + } +} diff --git a/example29-handle-multiple-channel/main.go b/example29-handle-multiple-channel/main.go new file mode 100644 index 0000000..bd994c4 --- /dev/null +++ b/example29-handle-multiple-channel/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +func main() { + wg := sync.WaitGroup{} + wg.Add(100) + for i := 0; i < 100; i++ { + go func(val int, wg *sync.WaitGroup) { + time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond) + fmt.Println("finished job id:", val) + wg.Done() + }(i, &wg) + } + + wg.Wait() +}