Go通道channel通過通信共享內存

 更新時間:2022年07月05日 17:25:29   作者:LiberHome  
這篇文章主要為大家介紹了Go通道channel通過通信共享內存示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

不要通過共享內存來通信 應該通過通信來共享內存

這句話有網友的解釋如下:

這句俏皮話具體說來就是,不同的線程不共享內存不用鎖,線程之間通訊用通道(channel)同步也用channel。

chanel是協程之間傳遞信息的媒介,優雅地解決了某些后端開發常用語言中隨處可見的lock,unlock,臨界區等,把從很多線程層面解決的問題移到協程,從而靜態地保證沒有數據競爭。

通道的聲明與創建

偽代碼如下:

//聲明類型
var 通道名 chan 數據類型
//創建通道
通道名 = make(chan 數據類型)

實際例子如下:

package main
import "fmt"
func main() {
    var a chan int
    fmt.Printf("%T, %v\n", a, a)
    if a == nil {
        a = make(chan int)
        fmt.Printf("%T, %v\n", a, a)
    }
}

運行結果是:

chan int, <nil>
chan int, 0x1400001a360

通道是一個內存地址,這也說明了其實一個引用類型的數據。

接收 & 發送數據

對于同一個通道來講,他的讀數據 和 寫數據 都是阻塞的。
偽代碼如下:

//從通道讀數據
data := <-a
//把數據寫入通道
a <- data

實際例子如下:

package main
import "fmt"
func main() {
    //    首先創建一個bool類型的通道
    var ch1 chan bool
    ch1 = make(chan bool)
    //下面啟動一個go routine
    go func() {
        for i := 0; i &lt; 10; i++ {
            fmt.Println("子goroutine中, i: ", i)
        }
        fmt.Println("completed")
        //循環結束后 向團隊中寫數據,表示要結束了
        ch1 &lt;- true
    }()
    //在主程序中讀取數據
    data := &lt;-ch1
    //打印一下 我們讀到的數據
    fmt.Println("main  data: ", data)
    fmt.Println("main goroutine completed")
}

運行結果如下:

子goroutine中, i: 0
子goroutine中, i: 1
子goroutine中, i: 2
子goroutine中, i: 3
子goroutine中, i: 4
子goroutine中, i: 5
子goroutine中, i: 6
子goroutine中, i: 7
子goroutine中, i: 8
子goroutine中, i: 9
completed
main data: true
main goroutine completed

我們的子goroutine里面 循環打印1~10, 打印完成之后 把chanel類型的ch1寫為true,
這時候,主goroutine就可以根據這一條件進行下一步了,,在此之前,其實就算主goroutine先搶到了資源,從ch1中讀取數據,但是現在通道里面啥都沒有,只能阻塞,然后乖乖交出資源給我們的子goroutine,直到循環結束寫true入ch1。

需要注意的有以下幾點:

  • chanel是需要指定類型的 nil類型的chanel不能直接使用。
  • chanel本身是同步的,同一時間只能有一條goroutine進行操作。
  • chanel是goroutine之間傳遞數據用的,chanel數據的發送和接收必須在不同的goroutine中,如果只有一條goroutine是用不上chanel的,這種情況會發生死鎖(deadLock)。
  • 從chanel里面讀數據立馬就會被阻塞,直到有向chanel寫數據的goroutine來。
  • 向chanel里面寫數據立馬就會被阻塞,直到有從chanel讀數據的goroutine來。

(以上都是相對于沒有緩存的通道而言,后面講到的緩存通道在緩沖區滿的時候才阻塞,而不是立刻阻塞)

以上就是Go通道channel通過通信共享內存的詳細內容,更多關于Go channel通信共享內存的資料請關注腳本之家其它相關文章!

相關文章

  • golang 結構體初始化時賦值格式介紹

    golang 結構體初始化時賦值格式介紹

    這篇文章主要介紹了golang 結構體初始化時賦值格式介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang語言中wasm 環境搭建的過程詳解

    golang語言中wasm 環境搭建的過程詳解

    將 golang 打包為 WASM,通常有兩種打包方式,一種是 golang 自帶的,另外是使用 tinygo ,接下來通過本文給大家介紹golang語言中wasm 環境搭建的過程,感興趣的朋友一起看看吧
    2021-11-11
  • go redis實現滑動窗口限流的方式(redis版)

    go redis實現滑動窗口限流的方式(redis版)

    這篇文章主要介紹了go redis實現滑動窗口限流的方式(redis版),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Go語言的接口詳解

    Go語言的接口詳解

    這篇文章主要介紹了go語言的接口,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧,希望能夠給你帶來幫助
    2021-10-10
  • Go pprof內存指標含義備忘錄及案例分析

    Go pprof內存指標含義備忘錄及案例分析

    這篇文章主要介紹了Go pprof內存指標含義備忘錄問題,小編特此把問題及案例分享到腳本之家平臺供大家學習,需要的朋友可以參考下
    2020-03-03
  • Go語言做爬蟲狀態碼返回418的問題解決

    Go語言做爬蟲狀態碼返回418的問題解決

    在使用Go語言做爬蟲時,使用http.Get(url)去獲取網頁內容,狀態碼返回404,本文我們就詳細的介紹一下解決方法,感興趣的可以了解一下
    2021-12-12
  • 基于Go和Gin的環境配置方法

    基于Go和Gin的環境配置方法

    今天小編就為大家分享一篇基于Go和Gin的環境配置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Go實現用戶每日限額的方法(例一天只能領三次福利)

    Go實現用戶每日限額的方法(例一天只能領三次福利)

    這篇文章主要介紹了Go實現用戶每日限額的方法(例一天只能領三次福利)
    2022-01-01
  • golang交叉編譯詳細

    golang交叉編譯詳細

    Golang 支持交叉編譯,在一個平臺上生成另一個平臺的可執行程序,只需要按照我下面的這個環境變量表設置對應的環境變量就可以了,下面文章將對該內容做詳細介紹,感興趣的小伙伴可以參考一下
    2021-10-10
  • 總結Go語言中defer的使用和注意要點

    總結Go語言中defer的使用和注意要點

    Go語言中的defer關鍵字實現比較特殊的功能,這篇文章給大家總結了關于Go語言中defer的使用和注意要點,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-09-09

最新評論

美丽人妻被按摩中出中文字幕