请求结果汇总
存在多个请求时,需要把最终多个结果汇总一起,结果的总线应时间不是简单的线性叠加,而是最耗时的执行函数决定了
package mainimport ("fmt""math/rand""time")func mockWebRequest(duration time.Duration)<-chan int{r := make(chan int)go func() {time.Sleep(time.Second*duration)r<-rand.Intn(100)}()return r}func AddResult(a,b int)int {fmt.Printf("a=%d b=%d\n",a,b)return a+b}func main() {rand.Seed(time.Now().UnixNano())start := time.Now()// 模拟2个网络请求a := mockWebRequest(1)b := mockWebRequest(2)fmt.Println("result:",AddResult(<-a,<-b))// 最终执行时间主要有耗时支持的请求决定fmt.Println("exec time", time.Since(start))}
最终打印结果
a=89 b=64result: 153exec time 2.000173355s
当然上面这种效果也可以通过bufferchan 实现
package mainimport ("fmt""math/rand""time")func mockWebRequest(r chan<- int, duration time.Duration){time.Sleep(time.Second*duration)r<-rand.Intn(100)}func main() {rand.Seed(time.Now().UnixNano())start := time.Now()// 模拟3个网络请求c := make(chan int ,3)for i :=0;i<cap(c);i++{go mockWebRequest(c,time.Duration(i+1))}for i :=0;i<cap(c);i++{fmt.Println(<-c)}close(c)// 最终执行时间主要有耗时支持的请求决定fmt.Println("exec time", time.Since(start))}
多个请求结果取其1
默认闲聊回复我们接入了多个第三方api,保证一份数据可能同时从多个数据源获取结果。但是我们只需要多个中最快返回的结果就可以了。
package mainimport ("fmt""math/rand""time")func searchWord(engine string,c chan<- string, t time.Duration){fmt.Printf("%s mock search time=%d\n",engine,t)time.Sleep(time.Second*t)c <-engine+" search result"}func main() {c :=make(chan string)rand.Seed(time.Now().UnixNano())s :=time.Now()go searchWord("baidu",c,time.Duration(rand.Intn(10)))go searchWord("google",c,time.Duration(rand.Intn(10)))fmt.Println(<-c,"exex time=",time.Since(s))close(c)}
打印结果
google mock search time=3baidu mock search time=6google search result exex time= 3.00528376s
但是也可以使用select 处理最大超时阈值
package mainimport ("fmt""math/rand""time")func searchWord(engine string, c chan<- string, t time.Duration) {fmt.Printf("%s mock search time=%d\n", engine, t)time.Sleep(time.Second * t)c <- engine + " search result"}func main() {c := make(chan string)rand.Seed(time.Now().UnixNano())go searchWord("baidu", c, time.Duration(rand.Intn(10)))go searchWord("google", c, time.Duration(rand.Intn(10)))select {case r :=<-c:fmt.Println(r)case <-time.After(4*time.Second):fmt.Println("search time out")}}
buffer容量为1 实现锁的能力
package mainimport ("fmt""sync")var (c = make(chan struct{}, 1) //容量为1的缓冲信道sum int)func increment(x int, wg *sync.WaitGroup) {c <- struct{}{}sum += xwg.Done()<-c}func main() {var wg sync.WaitGroupv := 100for i := 1; i <= v; i++ {wg.Add(1)go increment(i, &wg)}wg.Wait()fmt.Println(fmt.Sprintf("1-%d的和是:%d", v, sum))}
close 通知机制
package mainimport ("fmt""math/rand")import "time"func worker(id int, ready <-chan struct{}, done chan<- string) {<-ready // 阻塞在此,等待通知fmt.Println("Worker", id, "start")// 模拟一个工作负载。time.Sleep(time.Second * time.Duration(rand.Intn(10)))done <- fmt.Sprintf("Worker %d finish",id) // 数据回传}func main() {rand.Seed(time.Now().UnixNano())ready, done := make(chan struct{}), make(chan string)for i :=1;i<=3;i++{go worker(i, ready, done)}// 模拟数据初始化过程time.Sleep(time.Second)// 单对多通知close(ready)index := 0for v :=range done{fmt.Println(v)index++if index==3 {close(done)}}}
