佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 詳解Golang中Channel的用法

詳解Golang中Channel的用法

熱門標(biāo)簽:地方門戶網(wǎng)站 呼叫中心市場需求 百度競價排名 AI電銷 鐵路電話系統(tǒng) 網(wǎng)站排名優(yōu)化 Linux服務(wù)器 服務(wù)外包

如果說goroutine是Go語言程序的并發(fā)體的話,那么channels則是它們之間的通信機(jī)制。一個channel是一個通信機(jī)制,它可以讓一個goroutine通過它給另一個goroutine發(fā)送值信息。

1 創(chuàng)建channel

每個channel都有一個特殊的類型,也就是channels可發(fā)送數(shù)據(jù)的類型。一個可以發(fā)送int類型數(shù)據(jù)
的channel一般寫為chan int。使用內(nèi)置的make函數(shù),如果第二個參數(shù)大于0,則表示創(chuàng)建一個帶緩存的channel。

ch := make(chan int) // ch has type 'chan int'
ch = make(chan int, 3) // buffered channel with capacity 3

2 channel的發(fā)送和接受

一個發(fā)送語句將一個值從一個goroutine通過channel發(fā)送到另一個執(zhí)行接收操作的goroutine。發(fā)送和接收兩個操作都使用-運(yùn)算符。在發(fā)送語句中,-運(yùn)算符分割channel和要發(fā)送的值。在接收語句中,-運(yùn)算符寫在channel對象之前。一個不使用接收結(jié)果的接收操作也是合法的。

ch - x
// a send statement
x = -ch // a receive expression in an assignment statement
-ch
// a receive statement; result is discarded

3 channel的close

Channel還支持close操作,用于關(guān)閉channel,隨后對基于該channel的任何發(fā)送操作都將導(dǎo)致panic異常。對一個已經(jīng)被close過的channel進(jìn)行接收操作依然可以接受到之前已經(jīng)成功發(fā)送的數(shù)據(jù),如果channel中已經(jīng)沒有數(shù)據(jù)的話將產(chǎn)生一個零值的數(shù)據(jù)。使用內(nèi)置的close函數(shù)就可以關(guān)閉一個channel:

close(ch)

4 不帶緩存的Channels

一個基于無緩存Channels的發(fā)送操作將導(dǎo)致發(fā)送者goroutine阻塞,直到另一個goroutine在相同的Channels上執(zhí)行接收操作,當(dāng)發(fā)送的值通過Channels成功傳輸之后,兩個goroutine可以繼續(xù)執(zhí)行后面的語句。反之,如果接收操作先發(fā)生,那么接收者goroutine也將阻塞,直到有另一個goroutine在相同的Channels上執(zhí)行發(fā)送操作。
基于無緩存Channels的發(fā)送和接收操作將導(dǎo)致兩個goroutine做一次同步操作。因?yàn)檫@個原因,無緩存Channels有時候也被稱為同步Channels。

5 串聯(lián)的Channels

Channels也可以用于將多個goroutine連接在一起,一個Channel的輸出作為下一個Channel的輸入。這種串聯(lián)的Channels就是所謂的管道(pipeline)。

func main() {
	naturals := make(chan int)
	squares := make(chan int)
	// Counter
	go func() {
		for x := 0; x  100; x++ {
			naturals - x
		}
		close(naturals)
	}()
	// Squarer
	go func() {
		for x := range naturals {
			squares - x * x
		}
		close(squares)
	}()
	// Printer (in main goroutine)
	for x := range squares {
		fmt.Println(x)
	}
}

當(dāng)一個被關(guān)閉的channel中已經(jīng)發(fā)送的數(shù)據(jù)都被成功接收后,后續(xù)的接收操作將不再阻塞,它們會立即返回一個零值。
Go語言的range循環(huán)可直接在channels上面迭代。使用range循環(huán)依次從channel接收數(shù)據(jù),當(dāng)channel被關(guān)閉并且沒有值可接收時跳出循環(huán)。

6 單方向的Channels

為了防止被濫用,Go語言的類型系統(tǒng)提供了單方向的channel類型,分別用于只發(fā)送或只接收的channel。類型-chan int表示一個只接收int的channel, chan- int表示一個只發(fā)送int的channel,(箭頭-和關(guān)鍵字chan的相對位置表明了channel的方向。),這種限制將在編譯期檢測。

func counter(out chan- int) {
	for x := 0; x  100; x++ {
			out - x
		}
		close(out)
	}
	func squarer(out chan- int, in -chan int) {
		for v := range in {
			out - v * v
		}
		close(out)
	}
	func printer(in -chan int) {
		for v := range in {
			fmt.Println(v)
		}
	}
	func main() {
		naturals := make(chan int)
		squares := make(chan int)
		go counter(naturals)
		go squarer(squares, naturals)
		printer(squares)
}

7 帶緩存的Channels

帶緩存的Channel內(nèi)部持有一個元素隊列。隊列的最大容量是在調(diào)用make函數(shù)創(chuàng)建channel時通過第二個參數(shù)指定的。
向緩存Channel的發(fā)送操作就是向內(nèi)部緩存隊列的尾部插入元素,接收操作則是從隊列的頭部刪除元素。如果內(nèi)部緩存隊列是滿的,那么發(fā)送操作將阻塞直到因另一個goroutine執(zhí)行接收操作而釋放了新的隊列空間。相反,如果channel是空的,接收操作將阻塞直到有另一個goroutine執(zhí)行發(fā)送操作而向隊列插入元素。

  • write:緩沖區(qū)被填滿后,寫端才會阻塞。
  • read:緩沖區(qū)被讀空,讀端才會阻塞。

可以用內(nèi)置的cap函數(shù)獲取channel內(nèi)部緩存的容量

fmt.Println(cap(ch)) // "3"

可以用內(nèi)置的len函數(shù)獲取channel內(nèi)部緩存隊列中有效元素的個數(shù)。

fmt.Println(len(ch)) // "2"

到此這篇關(guān)于詳解Golang中Channel的用法的文章就介紹到這了,更多相關(guān)Golang中Channel用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Golang實(shí)現(xiàn)Directional Channel(定向通道)
  • Golang的select多路復(fù)用及channel使用操作
  • golang開發(fā)中channel使用
  • 基于golang channel實(shí)現(xiàn)的輕量級異步任務(wù)分發(fā)器示例代碼
  • golang中for循環(huán)遍歷channel時需要注意的問題詳解
  • golang 函數(shù)返回chan類型的操作

標(biāo)簽:湖南 黃山 湘潭 衡水 蘭州 銅川 崇左 仙桃

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解Golang中Channel的用法》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    仁寿县| 隆回县| 兴隆县| 江油市| 禄丰县| 博湖县| 桦南县| 利辛县| 东港市| 龙山县| 泰安市| 遂平县| 阿城市| 南开区| 靖西县| 三门峡市| 方正县| 张家界市| 乌拉特后旗| 安吉县| 孝义市| 东辽县| 玉屏| 郎溪县| 民乐县| 海门市| 建水县| 长阳| 嘉祥县| 会宁县| 凌源市| 浦城县| 瓦房店市| 汤原县| 额济纳旗| 绥滨县| 湘西| 安义县| 尚义县| 临清市| 娱乐|