请求结果汇总
存在多个请求时,需要把最终多个结果汇总一起,结果的总线应时间不是简单的线性叠加,而是最耗时的执行函数决定了
package main
import (
"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=64
result: 153
exec time 2.000173355s
当然上面这种效果也可以通过bufferchan 实现
package main
import (
"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 main
import (
"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=3
baidu mock search time=6
google search result exex time= 3.00528376s
但是也可以使用select 处理最大超时阈值
package main
import (
"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 main
import (
"fmt"
"sync"
)
var (
c = make(chan struct{}, 1) //容量为1的缓冲信道
sum int
)
func increment(x int, wg *sync.WaitGroup) {
c <- struct{}{}
sum += x
wg.Done()
<-c
}
func main() {
var wg sync.WaitGroup
v := 100
for 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 main
import (
"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 := 0
for v :=range done{
fmt.Println(v)
index++
if index==3 {
close(done)
}
}
}