真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Go語言中如何理解協(xié)程通信實(shí)現(xiàn)的消息傳遞篇

Go 語言中如何理解協(xié)程通信實(shí)現(xiàn)的消息傳遞篇,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作與策劃設(shè)計(jì),渦陽網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:渦陽等地區(qū)。渦陽做網(wǎng)站價(jià)格咨詢:18980820575

通過共享內(nèi)存實(shí)現(xiàn)協(xié)程通信,這種方式太過繁瑣,且維護(hù)成本高,Go 語言推薦使用消息傳遞實(shí)現(xiàn)并發(fā)通信,這種消息通信機(jī)制被稱為 channel,中文譯作「通道」,可理解為傳遞消息的通道。

通道是 Go 語言在語言級別提供的協(xié)程通信方式,它是一種數(shù)據(jù)類型,本身是并發(fā)安全的,我們可以使用它在多個(gè) goroutine 之間傳遞消息,而不必?fù)?dān)心通道中的數(shù)據(jù)被污染。

注:需要注意的是,通道是進(jìn)程內(nèi)的通信方式,因此通過通道傳遞對象的過程和調(diào)用函數(shù)時(shí)的參數(shù)傳遞行為比較一致,也可以傳遞指針。如果需要跨進(jìn)程通信,建議通過分布式系統(tǒng)的方法來解決,比如使用 Socket 或者 HTTP 等通信協(xié)議,Go 語言對于網(wǎng)絡(luò)方面也有非常完善的支持,學(xué)院君會(huì)在介紹完并發(fā)編程后介紹網(wǎng)絡(luò)通信。

前面我們說到通道是一種數(shù)據(jù)類型,和數(shù)組類型類似,一個(gè)通道只能傳遞一種類型的值,這個(gè)類型需要在聲明通道時(shí)指定。在使用通道時(shí),需要通過 make 進(jìn)行聲明,通道對應(yīng)的類型關(guān)鍵字是 chann

ch := make(chan int)

這里我們初始化了一個(gè)通道類型 ch,其中只能傳遞 int 類型的值。

我們可以把通道看作是一個(gè)先進(jìn)先出(FIFO)的隊(duì)列,通道中的元素會(huì)嚴(yán)格按照發(fā)送順序排列,繼而按照排列順序被接收,通道元素的發(fā)送和接收都可以通過 <- 操作符來實(shí)現(xiàn),發(fā)送時(shí)元素值在右,通道變量在左:

ch <- 1  // 表示把元素 1 發(fā)送到通道 ch

接收時(shí)通道變量在右,可以通過指定變量接收元素值:

element := <-ch

也可以留空表示忽略:

<-ch

這樣一來,通過箭頭指向我們就可以清楚的判斷是寫入數(shù)據(jù)到通道還是從通道讀取數(shù)據(jù),非常簡單形象。

在系統(tǒng)介紹通道類型的完整語法前,我們先看通過通道類型重寫上篇教程通過共享內(nèi)存實(shí)現(xiàn)協(xié)程通信的代碼,創(chuàng)建一個(gè) channel.go 文件,編寫代碼如下:

package main
import (    "fmt"    "time")
func add(a, b int, ch chan int) {    c := a + b    fmt.Printf("%d + %d = %d\n", a, b, c)    ch <- 1}
func main() {    start := time.Now()    chs := make([]chan int, 10)    for i := 0; i < 10; i++ {        chs[i] = make(chan int)        go add(1, i, chs[i])    }    for _, ch := range chs {        <- ch    }    end := time.Now()    consume := end.Sub(start).Seconds()    fmt.Println("程序執(zhí)行耗時(shí)(s):", consume)}

在這個(gè)例子中,我們首先定義了一個(gè)包含 10 個(gè)通道類型的數(shù)組 chs,并把數(shù)組中的每個(gè)通道分配給 10 個(gè)不同的協(xié)程。在每個(gè)協(xié)程的 add() 函數(shù)業(yè)務(wù)邏輯完成后,我們通過 ch <- 1 語句向?qū)?yīng)的通道中發(fā)送一個(gè)數(shù)據(jù)。在所有的協(xié)程啟動(dòng)完成后,我們再通過 <-ch 語句從通道數(shù)組 chs 中依次接收數(shù)據(jù)(不對結(jié)果做任何處理,相當(dāng)于寫入通道的數(shù)據(jù)只是個(gè)標(biāo)識(shí)而已,表示這個(gè)通道所屬的協(xié)程邏輯執(zhí)行完畢),直到所有通道數(shù)據(jù)接收完畢,然后打印主程序耗時(shí)并退出。

之所以上述這段代碼可以實(shí)現(xiàn)和「共享內(nèi)存+鎖」一樣的效果,是因?yàn)橥ǖ缹懭霐?shù)據(jù)和從通道接收數(shù)據(jù)都是原子操作,或者說是同步阻塞的,當(dāng)我們向某個(gè)通道寫入數(shù)據(jù)時(shí),就相當(dāng)于該通道被加鎖,直到寫入操作完成才能執(zhí)行從該通道讀取數(shù)據(jù)的操作,反過來,當(dāng)我們從某個(gè)通道讀取數(shù)據(jù)時(shí),其他協(xié)程也不能操作該通道,直到讀取完成,如果通道中沒有數(shù)據(jù),則會(huì)阻塞在這里,直到通道被寫入數(shù)據(jù)。因此,可以看到通道的發(fā)送和接收操作是互斥的,同一時(shí)間同一個(gè)進(jìn)程內(nèi)的所有協(xié)程對某個(gè)通道只能執(zhí)行發(fā)送或接收操作,兩者不可能同時(shí)進(jìn)行,這樣就保證了并發(fā)的安全性,數(shù)據(jù)不可能被污染。

綜上可知,上述示例代碼 main() 函數(shù)中的第二個(gè)循環(huán)會(huì)等到所有子協(xié)程執(zhí)行完畢后才能完成所有通道的接收操作。我們可以執(zhí)行下這段代碼,輸出結(jié)果如下:

Go 語言中如何理解協(xié)程通信實(shí)現(xiàn)的消息傳遞篇

程序耗時(shí)和共享內(nèi)存相當(dāng),但是代碼要簡潔的多,優(yōu)雅的多。當(dāng)然,本篇教程只是介紹了通道的最基本使用,接下來,我將花幾個(gè)教程的篇幅為大家系統(tǒng)介紹通道,并結(jié)合協(xié)程(goroutine)+通道(channel)為大家展現(xiàn) Go 并發(fā)編程的魅力。

關(guān)于Go 語言中如何理解協(xié)程通信實(shí)現(xiàn)的消息傳遞篇問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。


名稱欄目:Go語言中如何理解協(xié)程通信實(shí)現(xiàn)的消息傳遞篇
地址分享:http://weahome.cn/article/gjsejp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部