第一种模型:主线程等待所有协程完成,主线程阻塞等待所有协程完成。
package main
import (
"fmt"
"math/rand"
"time"
)
// go 协程应用之一
// 创建10个线程
//主线程阻塞,等待所有子线程计算完成
// 子线程完成把结果放在子线程中
func main() {
var testchan =make(chan int ,10)
for i:=0;i<10 ;i++ {
go child(testchan,i)
}
for i:=0;i<10 ;i++ {
a:=<-testchan
fmt.Println("协程完成:",a)
}
fmt.Println("主程完成")
}
func child(mychan chan int,index int ){
/*
这里遇到一个问题 线程休眠需要一个 time.Duration类型的参数,也就是int64
参数 此时必须将 int 转换成 time.Duration 参数类型
用 time.Duration(int(要转换的数据)) 即可转换
*/
time.Sleep(time.Second*time.Duration(rand.Intn(10)))
mychan<-index;
}
运行:
协程完成: 7 协程完成: 8 协程完成: 2 协程完成: 5 协程完成: 4 协程完成: 6 协程完成: 1 协程完成: 0 协程完成: 3 协程完成: 9 主程完成
第二种模型:生产者和消费者模型,生产一个消费一个,谁的速度过快谁等待。
package main
import (
"time"
"fmt"
"math/rand"
)
/*
chan 应用生产者和消费者模型
生产者每生产一个东西和消费者就消费一个东西
消费者消费东西速度过快,生产者者跟不上,消费者就阻塞.
生产者生产东西过快,消费者跟不上,生产者阻塞
叫做同步的生产与消费
如果想拥有一个生产缓冲区,缓存一下 可以设置chan 缓存 cpChan:=make(chan int ,4)
这样就变成非同步的生产与消费
*/
func main() {
cpChan:=make(chan int)
go consumer(cpChan)
go producter(cpChan)
time.Sleep(time.Second*10)
}
func producter(cpChan chan int) {
for i:=0; i<10;i++ {
fmt.Println("生产:",i)
cpChan<-i
time.Sleep(time.Millisecond*time.Duration(rand.Intn(1000)))
}
}
func consumer(cpChan chan int) {
for i:=0; i<10;i++ {
p1:=<-cpChan
fmt.Println("消费了",p1)
time.Sleep(time.Millisecond*time.Duration(rand.Intn(1000)))
}
}
运行结果:
生产: 0 消费了 0 生产: 1 消费了 1 生产: 2 消费了 2 生产: 3 消费了 3 生产: 4 消费了 4 生产: 5 消费了 5 生产: 6 消费了 6 生产: 7 消费了 7 生产: 8 消费了 8 生产: 9
消费了 9
两种chan 应用,go 写代码还是很爽快的。