请求结果汇总

存在多个请求时,需要把最终多个结果汇总一起,结果的总线应时间不是简单的线性叠加,而是最耗时的执行函数决定了

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. func mockWebRequest(duration time.Duration)<-chan int{
  8. r := make(chan int)
  9. go func() {
  10. time.Sleep(time.Second*duration)
  11. r<-rand.Intn(100)
  12. }()
  13. return r
  14. }
  15. func AddResult(a,b int)int {
  16. fmt.Printf("a=%d b=%d\n",a,b)
  17. return a+b
  18. }
  19. func main() {
  20. rand.Seed(time.Now().UnixNano())
  21. start := time.Now()
  22. // 模拟2个网络请求
  23. a := mockWebRequest(1)
  24. b := mockWebRequest(2)
  25. fmt.Println("result:",AddResult(<-a,<-b))
  26. // 最终执行时间主要有耗时支持的请求决定
  27. fmt.Println("exec time", time.Since(start))
  28. }

最终打印结果

  1. a=89 b=64
  2. result: 153
  3. exec time 2.000173355s

当然上面这种效果也可以通过bufferchan 实现

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. func mockWebRequest(r chan<- int, duration time.Duration){
  8. time.Sleep(time.Second*duration)
  9. r<-rand.Intn(100)
  10. }
  11. func main() {
  12. rand.Seed(time.Now().UnixNano())
  13. start := time.Now()
  14. // 模拟3个网络请求
  15. c := make(chan int ,3)
  16. for i :=0;i<cap(c);i++{
  17. go mockWebRequest(c,time.Duration(i+1))
  18. }
  19. for i :=0;i<cap(c);i++{
  20. fmt.Println(<-c)
  21. }
  22. close(c)
  23. // 最终执行时间主要有耗时支持的请求决定
  24. fmt.Println("exec time", time.Since(start))
  25. }

多个请求结果取其1

默认闲聊回复我们接入了多个第三方api,保证一份数据可能同时从多个数据源获取结果。但是我们只需要多个中最快返回的结果就可以了。

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. func searchWord(engine string,c chan<- string, t time.Duration){
  8. fmt.Printf("%s mock search time=%d\n",engine,t)
  9. time.Sleep(time.Second*t)
  10. c <-engine+" search result"
  11. }
  12. func main() {
  13. c :=make(chan string)
  14. rand.Seed(time.Now().UnixNano())
  15. s :=time.Now()
  16. go searchWord("baidu",c,time.Duration(rand.Intn(10)))
  17. go searchWord("google",c,time.Duration(rand.Intn(10)))
  18. fmt.Println(<-c,"exex time=",time.Since(s))
  19. close(c)
  20. }

打印结果

  1. google mock search time=3
  2. baidu mock search time=6
  3. google search result exex time= 3.00528376s

但是也可以使用select 处理最大超时阈值

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. func searchWord(engine string, c chan<- string, t time.Duration) {
  8. fmt.Printf("%s mock search time=%d\n", engine, t)
  9. time.Sleep(time.Second * t)
  10. c <- engine + " search result"
  11. }
  12. func main() {
  13. c := make(chan string)
  14. rand.Seed(time.Now().UnixNano())
  15. go searchWord("baidu", c, time.Duration(rand.Intn(10)))
  16. go searchWord("google", c, time.Duration(rand.Intn(10)))
  17. select {
  18. case r :=<-c:
  19. fmt.Println(r)
  20. case <-time.After(4*time.Second):
  21. fmt.Println("search time out")
  22. }
  23. }

buffer容量为1 实现锁的能力

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var (
  7. c = make(chan struct{}, 1) //容量为1的缓冲信道
  8. sum int
  9. )
  10. func increment(x int, wg *sync.WaitGroup) {
  11. c <- struct{}{}
  12. sum += x
  13. wg.Done()
  14. <-c
  15. }
  16. func main() {
  17. var wg sync.WaitGroup
  18. v := 100
  19. for i := 1; i <= v; i++ {
  20. wg.Add(1)
  21. go increment(i, &wg)
  22. }
  23. wg.Wait()
  24. fmt.Println(fmt.Sprintf("1-%d的和是:%d", v, sum))
  25. }

close 通知机制

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. )
  6. import "time"
  7. func worker(id int, ready <-chan struct{}, done chan<- string) {
  8. <-ready // 阻塞在此,等待通知
  9. fmt.Println("Worker", id, "start")
  10. // 模拟一个工作负载。
  11. time.Sleep(time.Second * time.Duration(rand.Intn(10)))
  12. done <- fmt.Sprintf("Worker %d finish",id) // 数据回传
  13. }
  14. func main() {
  15. rand.Seed(time.Now().UnixNano())
  16. ready, done := make(chan struct{}), make(chan string)
  17. for i :=1;i<=3;i++{
  18. go worker(i, ready, done)
  19. }
  20. // 模拟数据初始化过程
  21. time.Sleep(time.Second)
  22. // 单对多通知
  23. close(ready)
  24. index := 0
  25. for v :=range done{
  26. fmt.Println(v)
  27. index++
  28. if index==3 {
  29. close(done)
  30. }
  31. }
  32. }