欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Go語(yǔ)言之通道

上一篇我們講的原子函數(shù)和互斥鎖,都可以保證共享數(shù)據(jù)的讀寫。但是呢,它們還是有點(diǎn)復(fù)雜,而且影響性能。對(duì)此,Go又為我們提供了一種工具,這就是通道。

目前創(chuàng)新互聯(lián)已為超過千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、合作網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。


所以在多個(gè)goroutine并發(fā)中,我們不僅可以通過原子函數(shù)和互斥鎖保證對(duì)共享資源的安全訪問,消除競(jìng)爭(zhēng)的狀態(tài),還可以通過使用通道,在多個(gè)goroutine發(fā)送和接受共享的數(shù)據(jù),達(dá)到數(shù)據(jù)同步的目的。


通道,它有點(diǎn)像在兩個(gè)routine之間架設(shè)的管道:一個(gè)goroutine可以往這個(gè)管道里塞數(shù)據(jù),另外一個(gè)可以從這個(gè)管道里取數(shù)據(jù)。有點(diǎn)類似于我們說的隊(duì)列。


聲明一個(gè)通道很簡(jiǎn)單,我們使用chan關(guān)鍵字即可。除此之外,還要指定通道中發(fā)送和接收數(shù)據(jù)的類型,這樣我們才能知道,要發(fā)送什么類型的數(shù)據(jù)給通道,也知道從這個(gè)通道里可以接收到什么類型的數(shù)據(jù)。


ch:=make(chan int)


通道類型和Map這些類型一樣,可以使用內(nèi)置的make函數(shù)聲明初始化。這里我們初始化了一個(gè)chan int類型的通道,所以我們只能往這個(gè)通道里發(fā)送int類型的數(shù)據(jù),當(dāng)然接收也只能是int類型的數(shù)據(jù)。


我們知道,通道是用于在goroutine之間通信的,它具有發(fā)送和接收兩個(gè)操作,而且這兩個(gè)操作的運(yùn)算符都是<-。


ch<-2//發(fā)送數(shù)值2給這個(gè)通道
x:=<-ch//從通道里讀取值,并把讀取的值賦值給x變量
<-ch//從通道里讀取值,然后忽略


看例子,慢慢理解發(fā)送和接收的用法。發(fā)送操作<-在通道的后面,看箭頭方向,表示把數(shù)值 2 發(fā)送到通道ch里;接收操作<-在通道的前面,而且是一個(gè)一元操作符,看箭頭方向,表示從通道ch里讀取數(shù)據(jù)。讀取的數(shù)據(jù)可以賦值給一個(gè)變量,也可以忽略。


通道我們還可以使用內(nèi)置的close函數(shù)關(guān)閉。


close(ch)


如果一個(gè)通道被關(guān)閉了,我們就不能往這個(gè)通道里發(fā)送數(shù)據(jù)了,如果發(fā)送的話,會(huì)引起painc異常。但是,我們還可以接收通道里的數(shù)據(jù),如果通道里沒有數(shù)據(jù)的話,接收的數(shù)據(jù)是nil。


剛剛我們使用make函數(shù)初始化的時(shí)候,只有一個(gè)參數(shù),其實(shí)make還可以有第二個(gè)參數(shù),用于指定通道的大小。默認(rèn)沒有第二個(gè)參數(shù)的時(shí)候,通道的大小為 0 ,這種通道也被成為無緩沖通道。


ch:=make(chanint)
ch:=make(chanint,0)
ch:=make(chanint,2)


看例子,其中第一個(gè)和第二個(gè)初始化是等價(jià)的。第三個(gè)初始化創(chuàng)建了一個(gè)大小為 2 的通道,這種稱為有緩沖通道。


無緩沖的通道


無緩沖的通道指的是通道的大小為 0 。也就是說,這種類型的通道在接收前沒有能力保存任何值,它要求發(fā)送goroutine和接收goroutine同時(shí)準(zhǔn)備好,才可以完成發(fā)送和接收操作。


從上面無緩沖的通道定義來看,發(fā)送goroutine和接收gouroutine必須是同步的。同時(shí)準(zhǔn)備后,如果沒有同時(shí)準(zhǔn)備好的話,先執(zhí)行的操作就會(huì)阻塞等待,直到另一個(gè)相對(duì)應(yīng)的操作準(zhǔn)備好為止。這種無緩沖的通道我們也稱之為同步通道。


func main() {
    ch := make(chan int)
    go func() {
            var sum int = 0
            for i := 0; i < 10; i++ {
                sum += i            }
            ch <- sum    }()

    fmt.Println(<-ch)}


在前面的例子中,我們?yōu)榱搜菔緂oroutine,防止程序提前終止,都是使用sync.WaitGroup進(jìn)行等待?,F(xiàn)在的這個(gè)例子就不用了,我們使用同步通道來等待。


在計(jì)算sum和的goroutine沒有執(zhí)行完,把值賦給ch通道之前,fmt.Println(<-ch)會(huì)一直等待,所以main主goroutine就不會(huì)終止。只有當(dāng)計(jì)算和的goroutine完成,并且發(fā)送到ch通道的操作準(zhǔn)備好后,同時(shí)<-ch就會(huì)接收計(jì)算好的值,然后打印出來。


管道


我們?cè)谑褂肂ash的時(shí)候,有個(gè)管道操作|。它的意思是把上一個(gè)操作的輸出,當(dāng)成下一個(gè)操作的輸入,連起來,做一連串的處理操作。


  ~ ls|grep'D'
Desktop
Documents
Downloads


比如上面這個(gè)例子的意思是,先使用ls命令,把當(dāng)前目錄下的目錄和文件列出來,作為下一個(gè)grep命令的輸入,然后通過grep命令,匹配我們需要顯示的目錄和文件,這里匹配以D開頭的文件名或者目錄名。


其實(shí)我們使用通道也可以做到管道的效果,我們只需要把一個(gè)通道的輸出,當(dāng)成下一個(gè)通道的輸入即可。


func main() {
    one := make(chan int)
    two := make(chan int)
    go func() {
        one<-100
    }()
    go func() {
        v:=<-one
        two<-v    }()

    fmt.Println(<-two)}


這里例子中我們定義兩個(gè)通道one和two,然后按照順序,先把 100 發(fā)送給通道one,然后用另外一個(gè)goroutine從one接收值,再發(fā)送給通道two,最終在主goroutine里等著接收打印two通道里的值。這就類似于一個(gè)管道的操作,把通道one的輸出,當(dāng)成通道two的輸入,類似于接力賽一樣。


有緩沖的通道


有緩沖通道,其實(shí)是一個(gè)隊(duì)列,這個(gè)隊(duì)列的最大容量就是我們使用make函數(shù)創(chuàng)建通道時(shí),通過第二個(gè)參數(shù)指定的。


ch := make(chan int, 3)


這里創(chuàng)建容量為 3 的、有緩沖的通道。對(duì)于有緩沖的通道,向其發(fā)送操作就是向隊(duì)列的尾部插入元素,接收操作則是從隊(duì)列的頭部刪除元素,并返回這個(gè)剛剛刪除的元素。


當(dāng)隊(duì)列滿的時(shí)候,發(fā)送操作會(huì)阻塞;當(dāng)隊(duì)列空的時(shí)候,接受操作會(huì)阻塞。有緩沖的通道,不要求發(fā)送和接收操作是同步的,相反可以解耦發(fā)送和接收操作。


想知道通道的容量以及里面有幾個(gè)元素?cái)?shù)據(jù)怎么辦?其實(shí)和map一樣,使用cap和len函數(shù)就可以了。


cap(ch)
len(ch)


cap函數(shù)返回通道的最大容量,len函數(shù)返回現(xiàn)在通道里有幾個(gè)元素。


func mirroredQuery() string {
    responses := make(chan string, 3)
    go func() { responses <- request("asia.gopl.io") }()
    go func() { responses <- request("europe.gopl.io") }()    
    go func() { responses <- request("americas.gopl.io") }()    
    return <-responses // return the quickest response}func request(hostname string) (response string) { /* ... */ }


這是Go語(yǔ)言圣經(jīng)里比較有意義的一個(gè)例子,例子是想獲取服務(wù)端的一個(gè)數(shù)據(jù),不過這個(gè)數(shù)據(jù)在三個(gè)鏡像站點(diǎn)上都存在,這三個(gè)鏡像分散在不同的地理位置,而我們的目的又是想最快地獲取數(shù)據(jù)。


所以這里,我們定義了一個(gè)容量為 3 的通道responses,然后同時(shí)發(fā)起 3 個(gè)并發(fā)goroutine向這三個(gè)鏡像獲取數(shù)據(jù),獲取到的數(shù)據(jù)發(fā)送到通道responses中,最后我們使用return <-responses返回獲取到的第一個(gè)數(shù)據(jù),也就是最快返回的那個(gè)鏡像的數(shù)據(jù)。


單向通道


有時(shí)候,我們有一些特殊場(chǎng)景,比如限制一個(gè)通道只可以接收,但是不能發(fā)送;有時(shí)候限制一個(gè)通道只能發(fā)送,但是不能接收,這種通道我們稱為單向通道。


定義單向通道也很簡(jiǎn)單,只需要在定義的時(shí)候,帶上<-即可。


var send chan<-int//只能發(fā)送
var receive<-chanint//只能接收


注意<-操作符的位置,在后面是只能發(fā)送,對(duì)應(yīng)發(fā)送操作;在前面是只能接收,對(duì)應(yīng)接收操作。


單向通道應(yīng)用于函數(shù)或者方法的參數(shù)比較多,比如:


func counter(out chan<-int){
}


例子這樣的,只能進(jìn)行發(fā)送操作,防止使用接收操作。如果使用了接收操作,在編譯的時(shí)候就會(huì)報(bào)錯(cuò)的。


使用通道可以很簡(jiǎn)單地在goroutine之間共享數(shù)據(jù),下一篇會(huì)具體介紹一些例子,以便更好地理解并發(fā)。

當(dāng)前名稱:Go語(yǔ)言之通道
分享鏈接:http://aaarwkj.com/article34/pcdcse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、網(wǎng)站維護(hù)網(wǎng)站營(yíng)銷、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
欧美一区日韩二区国产三区| 亚洲男人天堂中文字幕| 欧美一区二区三区人妻熟妇| 欧美日韩一区二区黄色| 国产一区免费二区三区四区| 国产午夜18久久久| 亚洲午夜一区二区三区精品| 国产精品又大又黑又长又粗| 亚洲国产综合六月深深爱| 伊人久久亚洲精品综合| 四虎精品永久在线视频| 亚洲免费一区二区三区精品| 午夜福利影片免费观看| 我的极品小姨在线观看| 最新日韩人妻中文字幕一区| 91福利社区欧美大片| 精品人妻一区二区av| 亚洲综合香蕉在线视频| 国产精品无卡无在线播放| 九九精品在线观看视频| 国产精品兄妹在线观看91| 国产aaa级日本一区二区三区 | 98热这里只有精品视频| 麻豆人妻一区二区三区| 国产精品国产三级区| 欧美日韩人美精品一区在线| 2021亚洲精品午夜精品国产| 亚洲福利网址一二三区| 男女性视频在线免费观看| 亚洲黄色大片在线免费观看| av在线男人社区日韩| 一区二区三区毛片av网站| 国产精品白浆大屁股一区二区三 | 亚洲av成人在线播放| 偷拍偷窥女厕一区二区视频| 亚洲一区在线观看蜜臀| 人人爽人人妻人人澡| 亚洲日本中文字幕免费观看| 天堂av在线播放观看| 久久亚洲精品中文字幕| 日日做日夜夜操天天搞|