1. 程式人生 > 其它 >GO總結七管道與select

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,結束阻塞狀態
在這裡插入圖片描述