GO总结七管道与select

一 有缓冲管道与无缓冲管道

上一篇协程最后的同步时用无缓冲管道进行同步,无缓冲就是管道没有容量,放了东西必须拿走才能再次放,否则就阻塞。有缓冲管道可以指定管道容量,当管道满了,才会进行阻塞。使用有缓冲管道对协程进行通信,就会有异步的问题。

无缓冲管道的创建 ch := make(chan int)

有缓冲管道的创建 ch := make(chan int,3)//管道容量3

二 单向管道

单向管道就是只能读或者只能写

package main

import (
	"fmt"
)

func readNum(ch <-chan int){
	for num := range ch{
		
		fmt.Printf("read num=%d\n",num)
	}
}
	
func writeNum(ch chan<- int){
	
	num := 123
	fmt.Printf("write num=%d\n",num)
	ch<- num
	close(ch)
}

func main() {

	ch := make(chan int)
		
	//var wrch chan<- int = ch//只写
	//var rach <-chan int = ch//只读
	
	go writeNum(ch)
	readNum(ch)
	
	fmt.Println("main")
}

在这里插入图片描述
单向管道不能转换为双向,双向可以转换为单向。

三 select多路复用与超时机制

select是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收
select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的

package main

import (
	"fmt"
)

func readNum(ch <-chan int,quit <-chan bool){
	for {
		select{
			case num :=<- ch:
				fmt.Printf("read num=%d\n",num)				
			case <- quit:
				fmt.Println("quit")
				return		
		}		
	}
}
	

func main() {

	ch := make(chan int)
	quit := make(chan bool)
	
	go func (ch chan<- int,quit chan<- bool){	
		var num int
		for i:= 1;i<5;i++{
			num= i*i*i
			ch<- num
		}
		quit<- true
		close(quit)
		close(ch)
	}(ch,quit)
		
	readNum(ch,quit)	

}

在这里插入图片描述
超时机制

package main

import (
	"fmt"
	"time"
)

func readNum(ch <-chan int){
	for {
		select{
			case num :=<- ch:
				fmt.Printf("read num=%d\n",num)				
			case <- time.After(3*time.Second)://超过三秒没有响应,自动退出
				fmt.Println("quit")
				return		
		}		
	}
}
	

func main() {

	ch := make(chan int)
	
	go func (ch chan<- int){	
		var num int
		for i:= 1;i<5;i++{
			num= i*i*i
			ch<- num
		}
	}(ch)
		
	readNum(ch)	
}

结果,当输出后,没有响应,自动打印quit,结束阻塞状态
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/GreedySnaker/article/details/114483856