Golang 協(xié)程配合管道的實現(xiàn)示例
請完成goroutine和channel協(xié)同工作的案例,具體要求:
(1)開啟一個writeData協(xié)程,向管道m(xù)tChan中寫入50個整數(shù).
(2)開啟一個readData協(xié)程,從管道intChan中讀取writeData寫入的數(shù)據(jù)。
(3)注意:writeData和readDate操作的是同一個管道
(4)主線程需要等待writeData和readDate協(xié)程都完成工作才能退出(如果主線程不做處理,那么其他線程還沒干完活就直接跑路了)
管道是引用類型,那么寫入讀取的都是同一個管道,也就是在不同函數(shù)不同棧里面讀取的都是同一個管道。兩個協(xié)程同時的向管道里面寫入讀取數(shù)據(jù),而不是一個寫完另外一個協(xié)程再去讀取。
package main import ( "fmt" ) func writeData(initChan chan int) { for i := 0; i <= 50; i++ { //放入數(shù)據(jù) initChan <- i fmt.Println("write data:", i) } close(initChan) } func readData(initChan chan int, exitChan chan bool) { //即使管道close之后并不影響讀取,當在管道當中取不到數(shù)據(jù)才會退出 for { //在從一個管道里面讀取會返回兩個值,ok是有沒有正確讀取到 v, ok := <-initChan if !ok { break } fmt.Println("read data:", v) } //readData任務完成之后 exitChan <- true close(exitChan) } func main() { //創(chuàng)建兩個管道 initChan := make(chan int, 50) exitChan := make(chan bool, 1) go writeData(initChan) go readData(initChan, exitChan) for { _, ok := <-exitChan fmt.Println("ok=", ok) if ok { break } } }
如果給的容量就是50,那么循環(huán)50次就剛好放進去了。如果管道和放進去的數(shù)據(jù)量不匹配,管道的容量小于放進去的數(shù)據(jù),又不取出來,那么它就會阻塞,就會死鎖。
這個管道可以容納的數(shù)據(jù)量很小,要寫的數(shù)據(jù)量很大,只要一邊在寫,另外一邊在讀是無所謂的。
如果寫的快,讀取的慢。那么在寫的時候就會阻塞,編譯器會發(fā)現(xiàn)雖然阻塞了,但是有另外一個協(xié)程在往里面讀取數(shù)據(jù),這樣就不會發(fā)生死鎖。
func producer(ch chan int) { i := 0 for { ch <- i i++ } } func main() { ch := make(chan int, 2) go producer(ch) for { fmt.Println(<-ch) time.Sleep(time.Second * 2) } } 0 1 2 3 4 5 6 7 進程 已完成,退出代碼為 -1073741510 (0xC000013A: interrupted by Ctrl+C)
死鎖編譯器底層會分析,如果發(fā)現(xiàn)一個地方在不停的寫,但是沒有任何一個協(xié)程去讀取這樣就直接死鎖,如果有一個協(xié)程在慢慢的讀取這樣不會死鎖。和寫入讀取速度沒有關系,但是必須有寫入的協(xié)程和讀取的協(xié)程。簡而言之就是管道需要不停的流動。
到此這篇關于Golang 協(xié)程配合管道的文章就介紹到這了,更多相關Golang 協(xié)程配合管道內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Golang實現(xiàn)Excel表格的導入導出功能
最近項目開發(fā)中有涉及到Excel的導入與導出功能,特別是導出表格時需要特定的格式,所以本文給大家介紹了基于Golang實現(xiàn)Excel表格的導入導出功能,文中通過代碼示例和圖文介紹的非常詳細,需要的朋友可以參考下2023-12-12