go goroutine之间的调度-select

mac2026-09-29  5

package main import ( "fmt" "time" ) //生成数据 func generator() chan int { out := make(chan int) go func() { i := 0 for{ //向out中发送数据 out <- i i++ } }() //开完 goroutine 同时return return out } func createWorker(id int) chan<- int { c := make(chan int) go worker(id ,c) return c } //消费数据 func worker (id int ,c chan int){ for n := range c { //如果 生成数据的速度 > 发送数据出去的速度 time.Sleep(time.Second) /* worker:0 received:0 worker:0 received:3530411 worker:0 received:6836647 中间很多数据被冲掉,所以需要需要把接收到的数据存储下来,排队 */ fmt.Printf("worker:%d received:%d\n",id,n) } } /*通过通信来共享数据*/ func main() { var c1,c2 =generator() ,generator() //从c1 c2中接收数据 //n1 := <- c1 //n2 := <- c2 //如果想同时接收,谁来的快就先接收谁 select worker := createWorker(0) //n := 0 //存储收到的数据 var values []int //10秒钟之后会向channel送一个时间 signal := time.After(10 * time.Second) tick := time.Tick(time.Second) //定时 每隔一段时间送一个值过来 for{ var activeWorker chan<- int //只定义但是没有创建 ,在select 是可以正常运行的,但是不能被select到,因为是阻塞的 //接收到数据后hasValue = true, 将数据发送出去之后就没有数据了hasValue=false var activeValue int if len(values) > 0 { //有值得时候才make channel activeWorker= worker activeValue = values[0] //队列中第一个需要被处理的数据 } select {//从channel中非阻塞的接收或发送数据,使用select //c1,c2会等待一段时间才会发送数据 case n := <-c1://从c1中进来 //worker = <-n //invalid operation: <-n (receive from non-chan type int) //fmt.Println("received from c1",n) //将接收到的数据存储到value是中 values = append(values,n) case n := <-c2://从c2中进来 //worker = <- n //fmt.Println("received from c2",n) //将接收到的数据存储到value是中 values = append(values,n) //向worker中送数据 case activeWorker <- activeValue: //处理队列中第一个数据 //将处理的数据从队列中拿掉 values = values[1:] case <- tick: //每隔一段时间显示队列长度 fmt.Println("queue lenght=",len(values)) /* queue lenght= 537594 worker:0 received:0 */ case <- time.After(800*time.Millisecond): //每两次生成数据之间的时间差超过800毫秒 fmt.Println("timeout") case <-signal: //当10秒之后 收到停止信号 fmt.Println("bye bye") return } } }

 

最新回复(0)