欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言如何通過通信共享內(nèi)存

 更新時(shí)間:2023年11月30日 11:52:43   作者:frank  
這篇文章主要為大家介紹了Go語言如何通過通信共享內(nèi)存實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

介紹

Go 語言使用 goroutine 和 channel,可以實(shí)現(xiàn)通過通信共享內(nèi)存。

本文我們介紹 Go 語言怎么通過通信共享內(nèi)存。

goroutine 和 channel

在了解 Go 語言怎么通過通信共享內(nèi)存之前。我們需要先了解一些預(yù)備知識(shí),即 goroutine 和 channel 是什么?

goroutine :

goroutine 具有簡(jiǎn)單的模型:它是與其它 goroutine 并發(fā)運(yùn)行在同一地址空間的函數(shù)。

goroutine 是輕量級(jí)的,所有消耗幾乎就只有棧空間的分配。而且棧最開始是非常小的,所以他們很廉價(jià),僅在需要時(shí)才會(huì)隨著堆空間的分配(和釋放)而變化。

摘自「Effective Go - channels[1]」。

注意:goroutine 之所以取名為 goroutine,是因?yàn)楝F(xiàn)有的術(shù)語 - 線程、協(xié)程、進(jìn)程等等 - 無法準(zhǔn)確傳達(dá)它的含義。也有些資料將 goroutine 翻譯為 Go 協(xié)程或 Go 程。

使用 goroutine 也非常簡(jiǎn)單,在函數(shù)或方法前添加 go 關(guān)鍵字,即可在新的 goroutine 中調(diào)用它。當(dāng)調(diào)用完成后,該 goroutine 也會(huì)安靜地退出。

此外,匿名函數(shù)也可以在 goroutine 中調(diào)用。

關(guān)于 goroutine 的實(shí)現(xiàn)原理和調(diào)度器模型 GPM,感興趣的讀者朋友們可以自行查閱相關(guān)資料。

channel:

我們已了解,什么是 goroutine,以及怎么使用 goroutine 調(diào)用函數(shù)或方法、匿名函數(shù)。

但是,想要實(shí)現(xiàn) goroutine 之間的通信,我們還需要了解 channel

channel 需要使用內(nèi)置函數(shù) make 分配內(nèi)存,其結(jié)果值充當(dāng)了對(duì)底層數(shù)據(jù)結(jié)構(gòu)的引用。如果提供了一個(gè)可選的參數(shù),它就會(huì)為該 channel 設(shè)置緩沖區(qū)大小,否則,該 channel 則為無緩沖區(qū)的 channel。

關(guān)于 channel 的實(shí)現(xiàn)原理,感興趣的讀者朋友們可以閱讀「Golang 語言中的 channel 實(shí)現(xiàn)原理」。

需要注意的是,兩個(gè) goroutine 之間通過無緩沖區(qū)的 channel 通信時(shí),同步交換數(shù)據(jù)。

作為兩個(gè) goroutine 之間的通信管道,向 channel 中發(fā)送數(shù)據(jù)的 goroutine 稱為“發(fā)送者”,反之,從 channel 中接收數(shù)據(jù)的 goroutine 稱為“接收者”。

通過通信共享內(nèi)存

我們已經(jīng)基本了解 Go 語言的 goroutine 和 channel,接下來我們看一下兩個(gè) goroutine 之間怎么使用 channel (無緩沖區(qū)和緩沖區(qū))進(jìn)行通信?

無緩沖區(qū) channel:

示例代碼:

func main() {
 c := make(chan int) // 定義一個(gè)無緩沖區(qū) channel
 go func() {         // 啟動(dòng)一個(gè) goroutine 調(diào)用匿名函數(shù)
  fmt.Println("啟動(dòng)一個(gè) goroutine 調(diào)用匿名函數(shù)")
  c <- 1 // 該 goroutine 向 channel 發(fā)送一個(gè)值(信號(hào))
 }()
 fmt.Println("main 函數(shù)")
 out := <-c // main goroutine 從 channel 中接收一個(gè)值(信號(hào)),再未接收到值(信號(hào))之前,一直阻塞
 fmt.Println(out) // 該打印無實(shí)際意義,僅為了讀者容易理解
}

閱讀上面這段代碼,我們定義一個(gè)無緩沖區(qū) channel,執(zhí)行匿名函數(shù)的 goroutine 作為發(fā)送者,main goroutine 作為接收者。

需要注意的是,無緩沖區(qū) channel,接收者在收到值之前,發(fā)送者會(huì)一直阻塞。同理,發(fā)送者在發(fā)送值之前,接收者也會(huì)一直阻塞。

緩沖區(qū) channel:

示例代碼:

func main() {
  // c := make(chan int) // 無緩沖區(qū) channel
 c := make(chan int, 5) // 緩沖區(qū) channel
 for i := 0; i < 20; i++ {
  c <- 1
  go func() {
   fmt.Println("do something:", i)
   <-c
  }()
 }

 time.Sleep(time.Second * 2) // 為了防止 main goroutine 提前退出
}

閱讀上面這段代碼,我們定義一個(gè)緩沖區(qū)大小為 5 的 channel,執(zhí)行匿名函數(shù)的 goroutine 作為接收者,main goroutine 作為發(fā)送者。

需要注意的是,該段代碼中有 5 個(gè)執(zhí)行匿名函數(shù)的 goroutine,即 N 個(gè)接收者,1 個(gè)發(fā)送者(main goroutine)。

我們前面講過,接收者在收到值之前會(huì)一直阻塞,而無緩沖區(qū) channel 在接收者收到值之前,發(fā)送者會(huì)一直阻塞。

如果我們將上面這段代碼中的緩沖區(qū) channel 換成無緩沖區(qū) channelN - 1 個(gè)接收者在接收到值之前,發(fā)送者會(huì)一直阻塞,發(fā)送者阻塞,導(dǎo)致接收者一直接收不到值,也會(huì)一直阻塞,從而導(dǎo)致死鎖。

上面這段話有些拗口,讀者朋友們可以通過運(yùn)行使用無緩沖區(qū) channel 的代碼來幫助自己理解。

我們運(yùn)行使用緩沖區(qū)大小為 5 的 channel 的代碼,發(fā)現(xiàn)代碼可以正常運(yùn)行,發(fā)送者和接收者之間不會(huì)產(chǎn)生死鎖。

這是因?yàn)榫彌_區(qū) channel,發(fā)送者僅在值被復(fù)制到緩沖區(qū)之前阻塞,如果緩沖區(qū)已滿,發(fā)送者會(huì)一直阻塞,直到某個(gè)接收者取出一個(gè)值。

回到上面這段示例代碼中,執(zhí)行匿名函數(shù)的 N 個(gè) goroutine 作為接收者,在沒有收到 main goroutine 發(fā)送的數(shù)據(jù)之前,一直處于阻塞狀態(tài),直到作為發(fā)送者的 main goroutine 發(fā)送數(shù)據(jù)到緩沖區(qū) channel 中。

讀者朋友們?nèi)绻屑?xì)閱讀這段代碼,會(huì)發(fā)現(xiàn)上面這段代碼雖然不會(huì)產(chǎn)生死鎖,但是存在一個(gè) bug。

解決方案可以閱讀我們之前的一篇文章「Go 語言使用 goroutine 運(yùn)行閉包的“坑”」,限于篇幅,我就不在本文中贅述了。

總結(jié)

本文我們介紹 Go 語言中,什么是 goroutine 和 channel,其中 channel 分為無緩沖區(qū)和緩沖區(qū)。

在簡(jiǎn)單了解 goroutine 和 channel 后,我們又介紹怎么使用 channel,實(shí)現(xiàn)兩個(gè) goroutine 之間通信。

以上就是Go語言如何通過通信共享內(nèi)存的詳細(xì)內(nèi)容,更多關(guān)于Go語言通信共享內(nèi)存的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Go語言如何實(shí)現(xiàn)并發(fā)安全的map

    詳解Go語言如何實(shí)現(xiàn)并發(fā)安全的map

    go語言提供的數(shù)據(jù)類型中,只有channel是并發(fā)安全的,基礎(chǔ)map并不是并發(fā)安全的,本文為大家整理了三種實(shí)現(xiàn)了并發(fā)安全的map的方案,有需要的可以參考下
    2023-12-12
  • golang協(xié)程關(guān)閉踩坑實(shí)戰(zhàn)記錄

    golang協(xié)程關(guān)閉踩坑實(shí)戰(zhàn)記錄

    協(xié)程(coroutine)是Go語言中的輕量級(jí)線程實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于golang協(xié)程關(guān)閉踩坑的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Go語言反射獲取類型屬性和方法示例

    Go語言反射獲取類型屬性和方法示例

    這篇文章主要為大家介紹了本文將介紹?Go?反射?reflect.StructField?和?reflect.Method?相關(guān)的內(nèi)容,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 基于Golang+Vue編寫一個(gè)手機(jī)遠(yuǎn)程控制電腦的懶人工具

    基于Golang+Vue編寫一個(gè)手機(jī)遠(yuǎn)程控制電腦的懶人工具

    這篇文章主要為大家詳細(xì)介紹了如何基于Golang+Vue編寫一個(gè)手機(jī)遠(yuǎn)程控制電腦的懶人工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2024-11-11
  • Golang接口的定義與空接口及斷言的使用示例

    Golang接口的定義與空接口及斷言的使用示例

    在?Golang?中,接口是一種類型,它是由一組方法簽名組成的抽象集合。這篇文章主要為大家介紹了Golang接口的具體使用,希望對(duì)大家有所幫助,空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒有定義任何方法口,也因此,我們可以說所有類型都至少實(shí)現(xiàn)了空接口
    2023-04-04
  • golang http請(qǐng)求封裝代碼

    golang http請(qǐng)求封裝代碼

    這篇文章主要介紹了golang http請(qǐng)求封裝代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)庫表轉(zhuǎn)結(jié)構(gòu)體詳解

    Go實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)庫表轉(zhuǎn)結(jié)構(gòu)體詳解

    這篇文章主要為大家介紹了Go實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)庫表轉(zhuǎn)結(jié)構(gòu)體詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go語言中的匿名結(jié)構(gòu)體用法實(shí)例

    Go語言中的匿名結(jié)構(gòu)體用法實(shí)例

    這篇文章主要介紹了Go語言中的匿名結(jié)構(gòu)體用法,實(shí)例分析了匿名結(jié)構(gòu)體的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go語言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法

    Go語言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法

    這篇文章主要介紹了Go語言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法,實(shí)例分析了sort排序所涉及的方法與相關(guān)的使用技巧,需要的朋友可以參考下
    2015-02-02
  • Golang JSON的進(jìn)階用法實(shí)例講解

    Golang JSON的進(jìn)階用法實(shí)例講解

    這篇文章主要給大家介紹了關(guān)于Golang JSON進(jìn)階用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09

最新評(píng)論