1.定义2个管道两个协程,一个协程写数据,一个协程读取数据。主线程。实施监控读取完成 代码如下
package main
import (
"fmt"
)
func WriteData(wchan chan int){
for i:=0; i<50;i++{
wchan<-i;
//time.Sleep(time.Second*2);
fmt.Printf("wirte chan is %v\n",i);
}
close(wchan);//关闭管道
}
func ReadData(wchan chan int, exichan chan bool){
for {
v,ok:= <-wchan;
if !ok {
break;
}
//time.Sleep(time.Second*2);//读管道
fmt.Printf("read channle is %v\n",v);
}
exichan <- true;
close(exichan);
}
func main() {
wchan:=make(chan int,50);
exitchan:=make(chan bool,1);
go WriteData(wchan);
go ReadData(wchan,exitchan);
for {//使用for循环阻塞
bol,_:= <- exitchan;
if bol {
break;
}
}
fmt.Printf("master process is end\n");
}
2.使用3个协程完成sum求和问题
package main
import (
"fmt"
)
func WChan(wchan chan int){
for i:=0;i<2000;i++ {
wchan <- i;
//fmt.Printf("write data is %v\n",i);
}
close(wchan);
}
func ReadChan(wchan chan int,signelChan chan bool,mapchan chan map[interface{}]interface{}){
for {
num,ok:= <- wchan;
if !ok {
break;
}
//fmt.Printf("read data is %v\n",num);
sum:=0;
for j:=0;j<=num;j++ {
sum=sum+j;
}
tmpMap:=make(map[interface{}]interface{});
tmpMap[num]=sum;
mapchan <- tmpMap;//写入map管道
//fmt.Printf("num的数字为%vsum求和为%v\n",num,sum);
}
signelChan <-true;
close(signelChan);
}
func reeadMap(mapChan chan map[interface{}]interface{}){
for {
tmpMap,ok:= <-mapChan;
if !ok {
break;
}
for k,v:=range tmpMap {
fmt.Printf("key=%v value=%v\n",k,v);
}
}
}
func main(){
writechan:=make(chan int ,2000);//写管道
bolChan:=make(chan bool);//信号量管道
mapchan:=make(chan map[interface{}]interface{});
go WChan(writechan);
go ReadChan(writechan,bolChan,mapchan);
go reeadMap(mapchan);
for {
bol,_:= <-bolChan;
if !bol {
break;
}
}
}
3.使用协程模拟2个人打球过程
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
//设置随机数种子
func init(){
rand.Seed(time.Now().UnixNano())
}
var wg sync.WaitGroup
func hitball (name string, chanName chan int ) {
defer wg.Done()
for {
ball,ok:= <-chanName
if !ok { //通道关闭了
fmt.Printf("%s通道关闭了\n",name)
return
}
n := rand.Intn(4000)
if n%99==1 {
fmt.Printf("找到正确的数字了关闭通道\n")
close(chanName)
return
}
//没有的话数字加一
fmt.Printf("%s继续查找-数字变为%d\n",name,ball)
ball++
chanName <- ball
}
}
func main(){
court:=make(chan int)//无缓冲通道
wg.Add(2)
go hitball("xiaoming",court)
go hitball("liqiang",court)
court <- 1
wg.Wait()
}
思考案例:什么时候关闭通道合适
package main
//描述 这是通过给字写协程发送任务
//思考什么时候关闭通道合适?
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func Sum(index int , job chan int , result chan string){
for val:=range job {
jisuan:=val*val
str:=fmt.Sprintf("这是第%d工人,原始数据为%d 处理数据为%d",index,val,jisuan)
result <-str
}
wg.Done()
}
func main(){
workder:=20
job:=make(chan int)
result:=make(chan string)
//10个工人
workNum:=1
wg.Add(workNum)
for i:=0;i<workNum;i++ {
go Sum(i,job,result)
}
//接受任务一定要写在投递任务前面阻塞住
//思考:什么时候合适关闭协程
wg.Add(1)
go func () {
i:=0
for data:=range result {
fmt.Printf("%v\n",data)
if i >=workder-1 {
close(result)
}
i++
}
defer wg.Done()
}()
//投递任务
for first:=1;first <= workder;first++ {
time.Sleep(time.Millisecond*500)
job <- first
}
close(job)
wg.Wait()
}