channel 是go语言中不同goroutine之间通信一种方法
//定义一个channel c := make(chan bool)
//向channel中写入 c <- true //读取channel <-c
有缓存,写入或者读出后继续往下执行;
在读的地方,如果别的地方没有写入,则阻塞在那,等有写入时才,读出,继续执行下去;
在写的地方,如果别的地方没有读就会阻塞在写的这个地方,等带别的地方读出来;不被读掉就会阻塞;
无缓存通道只有读写同时发生是才不阻塞;
向一个通道中读或者写时,必须要有别的携程接受了这个参数;
取在读前面.有缓存是异步,无缓存是同步阻塞;
package main import ( "log" "sync" //"time" //延迟用 ) //channel 是一个引用类型 func main() { //demo1() //demo3() //demo4() //demo5() demo6() } //简单的迭代操作 func demo1(){ c := make(chan bool) //双向通道 go func(){ log.Println("gogogo!") c <- true //向channel c中输入 close(c) //当channel在迭代操作是,必须在某个地方关闭它,不然程序将会进入死锁 }() //go Go() //并发执行 //time.Sleep(2 *time.Second) // 延迟两秒中 //<-c //阻塞中只有当并发执行的方法中向c中输入是这边才继续往下执行 for v := range c{ //迭代操作c log.Println(v) } } func Go() { log.Println("gogogo!") } //单向通道 func demo2() { } //缓存:取在读前面.有缓存是异步,无缓存是同步阻塞; //有缓存:有缓存,就会写入或者读出后继续往下执行;无缓存通道只有读写同时发生是才不阻塞;向一个通道中读或者写时,必须要有别的携程接受了这个参数; //无缓存:在读的地方,如果别的地方没有写入,则阻塞在那,等有写入时才,读出,继续执行下去;在写的地方,如果别的地方没有读就会阻塞在写的这个地方,等带别的地方读出来;不被读掉就会阻塞; func demo3(){ //c := make(chan bool,1) //有缓存 c := make(chan bool) //无缓存 go func(){ log.Println("123") c <- true //写入 }() <- c //读出 } func demo4() { c := make(chan bool,10) //定义缓存为10 for i:=0;i< 10;i++ { go demo4Go(c,i) } for i:=0;i<10;i++ { //循环读出10次后结束 <-c } } func demo4Go(c chan bool,index int){ a := 1 for i := 0; i<1000000; i++ { a += i } log.Println(index,a) c <- true //循环一次向channel中写一次 } //创建任务组。WaitGrpup,并发执行,使用WaitGroup实现所有进程都完成 func demo5() { wg := sync.WaitGroup{} wg.Add(10) //添加十个任务 for i:=0;i< 10;i++ { go demo5Go(&wg,i) //wg传递为地址传递 } wg.Wait() //当全部任务完成后 继续执行 } func demo5Go(wg *sync.WaitGroup,index int){ a := 1 for i := 0; i<1000000; i++ { a += i } log.Println(index,a) wg.Done() //干掉一个任务 } func demo6(){ c1,c2 := make(chan int),make(chan string) //定义两个channel o := make(chan bool) //总channel go func(){ for { select { case v,ok := <- c1: if !ok { o<-true break } log.Println("c1",v) case v,ok := <-c2: if !ok { o<-true break } log.Println("c2",v) } } }() c1 <- 1 c2 <- "hello" c1 <- 2 c2 <- "world" close(c1) close(c2) <- o }