成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊協程和管道—管道

開發 前端
使用內置函數close可以關閉管道,當管道關閉后,就不能再向管道寫數據了,但是仍然可以從該管道讀取數據。

管道簡介

【1】管道(channel)特質介紹:

(1)管道本質就是一個數據結構-隊列

(2)數據是先進先出

(3)自身線程安全,多協程訪問時,不需要加鎖,channel本身就是線程安全的

(4)管道有類型的,一個string的管道只能存放string類型數據

管道入門案例

【1】管道的定義:

var 變量名 chan 數據類型

PS1:chan管道關鍵字

PS2:數據類型指的是管道的類型,里面放入數據的類型,管道是有類型的,int類型的管道只能寫入整數int

PS3:管道是引用類型,必須初始化才能寫入數據,即make后才能使用

【2】案例:

func main()  {
	//定義管道 、 聲明管道 ---> 定義一個int類型的管道
	var intChan chan int
	//通過make初始化:管道可以存放3個int類型的數據
	intChan = make(chan int, 3)

	//證明管道是引用類型:
	fmt.Printf("intChan的值: %v \n",intChan)

	//向管道存放數據:
	intChan <- -10
	num := 20
	intChan <- num
	intChan <- 40
	//注意:不能存放大于容量的數據:
	// intChan <- -80
	//輸出管道的長度:
	fmt.Printf("管道的實際長度:%v,管道的容量是:%v \n",len(intChan),cap(intChan))

	//在管道中讀取數據:
	num1 := <-intChan
	num2 := <-intChan
	num3 := <-intChan
	fmt.Println(num1)
	fmt.Println(num2)
	fmt.Println(num3)

	//注意:在沒有使用協程的情況下,如果管道的數據已經全部取出,那么再取就會報錯:
	// num4 := <-intChan
	// fmt.Println(num4)

	fmt.Printf("管道的實際長度:%v,管道的容量是:%v \n",len(intChan),cap(intChan))
}

管道的關閉

【1】管道的關閉:

使用內置函數close可以關閉管道,當管道關閉后,就不能再向管道寫數據了,但是仍然可以從該管道讀取數據。

【2】案例:

func main()  {
	var intChan chan int
	intChan = make(chan int, 3)
	intChan <- 10
	intChan <- 20
	//關閉管道:
	close(intChan)
	//再次寫入數據:--->報錯
	// intChan <- 30
	//當管道關閉后,讀取數據是可以的:
	num := <- intChan
	fmt.Println(num)
}

管道的遍歷

【1】管道的遍歷:

管道支持for-range的方式進行遍歷,請注意兩個細節

1)在遍歷時,如果管道沒有關閉,則會出現deadlock的錯誤

2)在遍歷時,如果管道已經關閉,則會正常遍歷數據,遍歷完后,就會退出遍歷。

【2】案例:

func main()  {
	var intChan chan int
	intChan = make(chan int, 100)
	for i := 0; i < 100; i++ {
		intChan <- i
	}

	//在遍歷前,如果沒有關閉管道,就會出現deadlock的錯誤
	//所以我們在遍歷前要進行管道的關閉
	// for v := range intChan {
	// 	fmt.Println("value = ",v)
	// }
	close(intChan)
	//遍歷:for-range
	for v := range intChan {
		fmt.Println("value = ",v)
	}
}

協程和管道協同工作案例

【1】案例需求:

請完成協程和管道協同工作的案例,具體要求:

1) 開啟一個writeData協程,向管道中寫入50個整數.

2) 開啟一個readData協程,從管道中讀取writeData寫入的數據。

3) 注意: writeData和readDate操作的是同一個管道

4) 主線程需要等待writeData和readDate協程都完成工作才能退出

【2】原理圖:

package main

import (
	"fmt"
	"time"
	"sync"
)

var wg sync.WaitGroup

//寫:
func writeData(intChan chan int)  {
	defer wg.Done()
	for i := 1; i <= 50; i++ {
		intChan <- i
		fmt.Println("寫入的數據為:",i)
		time.Sleep(time.Second)
	}	
	close(intChan)
}

//讀:
func readData(intChan chan int) {
	defer wg.Done()
	for v := range intChan {
		fmt.Println("讀取的數據為:",v)
		time.Sleep(time.Second)
	}
}

func main()  {
	//主線程
	//寫協程和讀協程共同操作同一個管道-》定義管道:
	intChan := make(chan int, 50)
	wg.Add(2)
	//開啟讀和寫的協程:
	go writeData(intChan)
	go readData(intChan)
	//主線程一直在阻塞,什么時候wg減為0了,就停止
	wg.Wait()
	fmt.Println("讀寫數據完成...")
}

運行結果:

聲明只讀只寫管道

【1】管道可以聲明為只讀或者只寫性質

【2】代碼:

package main

import (
	"fmt"
)

func main()  {
	//默認情況下,管道是雙向的--》可讀可寫:
	//聲明為只寫:
	// 管道具備<- 只寫性質
	var intChan chan<- int
	intChan = make(chan int, 3)
	intChan <- 10
	// 報錯
	// num := <- intChan
	fmt.Println("intChan:",intChan)

	//聲明為只讀:
	// 管道具備<- 只讀性質 
	var intChan2 <-chan int
	if intChan2 != nil {
		num1 := <- intChan2
		fmt.Println("num1:",num1)
	}
	// 報錯
	// intChan2 <- 30
}

管道的阻塞

【1】當管道只寫入數據,沒有讀取,就會出現阻塞:

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func writeData(intChan chan int)  {
	defer wg.Done()
	for i := 1; i < 10; i++ {
		intChan <- i
		fmt.Println("寫入的數據:",i)
	}
	close(intChan)
}

func readData(intChan chan int)  {
	defer wg.Done()
	for v := range intChan {
		fmt.Println("讀取的數據為:",v)
	}
}

func main()  {
	intChan := make(chan int, 10)

	wg.Add(2)
	go writeData(intChan)
	// go readData(intChan)
	wg.Wait()
}

運行結果

【2】寫的快,讀的慢(管道讀寫頻率不一致),不會出現阻塞問題:

package main

import (
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func writeData(intChan chan int)  {
	defer wg.Done()
	for i := 1; i < 10; i++ {
		intChan <- i
		fmt.Println("寫入的數據:",i)
	}
	close(intChan)
}

func readData(intChan chan int)  {
	defer wg.Done()
	for v := range intChan {
		fmt.Println("讀取的數據為:",v)
		time.Sleep(time.Second)
	}
}

func main()  {
	intChan := make(chan int, 10)

	wg.Add(2)
	go writeData(intChan)
	go readData(intChan)
	wg.Wait()
}

select功能

【1】select功能:解決多個管道的選擇問題,也可以叫做多路復用,可以從多個管道中隨機公平地選擇一個來執行

PS:case后面必須進行的是io操作,不能是等值,隨機去選擇一個io操作

PS:default防止select被阻塞住,加入default

【2】代碼:

package main

import (
	"fmt"
	"time"
)

func main()  {
	intChan := make(chan int, 1)
	go func ()  {
		time.Sleep(time.Second * 15)
		intChan <- 15
	}()
	stringChan := make(chan string, 1)
	go func ()  {
		time.Sleep(time.Second * 12)
		stringChan <- "hellocyz"
	}()

	//本身取數據就是阻塞的
	// fmt.Println(<-intChan)

	select {
		case v := <-intChan : fmt.Println("intChan:",v)
		case v := <-stringChan : fmt.Println("stringChan:",v)
		default: fmt.Println("防止select被阻塞")
	}
}

defer+recover機制處理錯誤

【1】問題原因:多個協程工作,其中一個協程出現panic,導致程序崩潰

【2】解決辦法:利用defer+recover捕獲panic進行處理,即使協程出現問題,主線程仍然不受影響可以繼續執行。

【3】案例:

package main

import (
	"fmt"
	"time"
)

//輸出數字:
func printNum()  {
	for i := 1; i <= 10; i++ {
		fmt.Println(i)	
	}
}

//做除法操作:
func divide()  {
	defer func ()  {
		err := recover()
		if err != nil {
			fmt.Println("devide()出現錯誤:",err)
		}
	}()
	num1 := 10
	num2 := 0
	result := num1 / num2
	fmt.Println(result)
}

func main()  {
	//啟動兩個協程:
	go printNum()
	go divide()
	time.Sleep(time.Second * 5)
}

結果:

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2022-11-21 06:55:08

golang協程

2018-09-10 08:45:04

Linux管道命令

2021-02-20 20:36:56

Linux無名管道

2023-11-29 07:10:50

python協程異步編程

2021-09-16 09:59:13

PythonJavaScript代碼

2021-04-25 09:36:20

Go協程線程

2020-02-19 14:16:23

kotlin協程代碼

2014-04-25 10:13:00

Go語言并發模式

2010-10-25 16:52:48

oracle管道函數

2021-08-04 16:19:55

AndroidKotin協程Coroutines

2014-07-02 21:20:56

CA TechnoloAPI

2020-04-17 08:34:39

Linux管道

2022-11-14 15:07:09

Linux管道

2023-11-17 11:36:59

協程纖程操作系統

2025-06-26 04:10:00

2025-02-08 09:13:40

2020-10-10 07:18:14

Linux系統編程管道

2020-12-15 16:13:21

DevSecOpsCICD

2021-12-09 06:41:56

Python協程多并發

2023-10-24 19:37:34

協程Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品久久久一区二区三区 | 精品国产欧美一区二区三区成人 | 国产精品国产亚洲精品看不卡15 | 亚洲欧美日韩在线一区二区 | 亚洲久久在线 | 在线中文字幕视频 | 亚洲国产网址 | 日韩精品免费在线观看 | 国产在线观看一区二区三区 | 狠狠综合网 | 毛片一区二区三区 | 亚洲欧美在线观看 | 成人高清在线 | 国产精品综合色区在线观看 | 精品国产视频 | 亚洲欧美激情四射 | 欧美精品第一页 | 色偷偷888欧美精品久久久 | 国产片侵犯亲女视频播放 | 久久精片 | 国产日韩欧美一区二区 | 亚洲精品一区二区三区蜜桃久 | 亚洲视频1区 | 亚洲综合大片69999 | 成人av激情| 国产一区二区不卡 | 久久青视频| 亚洲国产一区在线 | 日日夜夜精品视频 | 国产一区二区 | 亚洲精品久久久久久首妖 | 亚洲精品国产a久久久久久 午夜影院网站 | 国产欧美精品区一区二区三区 | 成人精品一区二区三区中文字幕 | 国产在线a | 九色国产 | 国产精品久久久久久久久久 | 天天干成人网 | 91精品国产综合久久国产大片 | 日本三级视频 | 黄色毛片大全 |