最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Go Channel 高級(jí)實(shí)踐

 更新時(shí)間:2018年08月30日 10:38:15   作者:sxssxs  
這篇文章主要介紹了淺談Go Channel 高級(jí)實(shí)踐,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

channel 是 golang 里相當(dāng)有趣的一個(gè)功能,在我使用 golang 編碼的經(jīng)驗(yàn)里,大部分事件都會(huì)是在享受 channel 和 goroutine 配合的樂(lè)趣。所以本文主要介紹 channel 的一些有趣的用法。

這里有 Oling Cat 翻譯的Go編程語(yǔ)言規(guī)范里關(guān)于 channel(信道)的描述:

信道提供了一種機(jī)制,它在兩個(gè)并發(fā)執(zhí)行的函數(shù)之間進(jìn)行同步,并通過(guò)傳遞(與該信道元素類型相符的)值來(lái)進(jìn)行通信。

這個(gè)個(gè)描述又乏味、又枯燥。在我第一次閱讀的時(shí)候,完全不明白這到底是個(gè)什么玩意。事實(shí)上,可以認(rèn)為 channel 是一個(gè)管道或者先進(jìn)先出隊(duì)列,非常簡(jiǎn)單且輕量。channel 并不是 Golang 首創(chuàng)的。它同樣作為內(nèi)置功能出現(xiàn)在其他語(yǔ)言中。在大多數(shù)情況下,它是一個(gè)又大、又笨、又復(fù)雜的消息隊(duì)列系統(tǒng)的一個(gè)功能。

本文主要講實(shí)踐,原理部分會(huì)一筆帶過(guò),關(guān)于 go 語(yǔ)言并發(fā)實(shí)現(xiàn)和內(nèi)存模型后續(xù)會(huì)有文章。

channel 實(shí)現(xiàn)的源碼不復(fù)雜,推薦閱讀,https://github.com/golang/go/blob/master/src/runtime/chan.go

channel 是干什么的

意義:channel 是用來(lái)通信的

實(shí)際上:(數(shù)據(jù)拷貝了一份,并通過(guò) channel 傳遞,本質(zhì)就是個(gè)隊(duì)列)

channel 應(yīng)該用在什么地方

核心:需要通信的地方

例如以下場(chǎng)景:

  • 通知廣播
  • 交換數(shù)據(jù)
  • 顯式同步
  • 并發(fā)控制
  • ...

記?。hannel 不是用來(lái)實(shí)現(xiàn)鎖機(jī)制的,雖然有些地方可以用它來(lái)實(shí)現(xiàn)類似讀寫(xiě)鎖,保護(hù)臨界區(qū)的功能,但不要這么用!

channel 用例實(shí)現(xiàn)

超時(shí)控制

// 利用 time.After 實(shí)現(xiàn)
func main() {
  done := do()
  select {
  case <-done:
    // logic
  case <-time.After(3 * time.Second):
    // timeout
  }
}

func do() <-chan struct{} {
  done := make(chan struct{})
  go func() {
    // do something
    // ...
    done <- struct{}{}
  }()
  return done
}

取最快的結(jié)果

比較常見(jiàn)的一個(gè)場(chǎng)景是重試,第一個(gè)請(qǐng)求在指定超時(shí)時(shí)間內(nèi)沒(méi)有返回結(jié)果,這時(shí)重試第二次,取兩次中最快返回的結(jié)果使用。
超時(shí)控制在上面有,下面代碼部分就簡(jiǎn)單實(shí)現(xiàn)調(diào)用多次了。

func main() {
  ret := make(chan string, 3)
  for i := 0; i < cap(ret); i++ {
    go call(ret)
  }
    fmt.Println(<-ret)
}

func call(ret chan<- string) {
  // do something
  // ...
  ret <- "result"
}

限制最大并發(fā)數(shù)

// 最大并發(fā)數(shù)為 2
limits := make(chan struct{}, 2)
for i := 0; i < 10; i++ {
  go func() {
    // 緩沖區(qū)滿了就會(huì)阻塞在這
    limits <- struct{}{}
    do()
    <-limits
  }()
}

for...range 優(yōu)先

for ... range c { do } 這種寫(xiě)法相當(dāng)于 if _, ok := <-c; ok { do }

func main() {
  c := make(chan int, 20)
  go func() {
    for i := 0; i < 10; i++ {
      c <- i
    }
    close(c)
  }()
  // 當(dāng) c 被關(guān)閉后,取完里面的元素就會(huì)跳出循環(huán)
  for x := range c {
    fmt.Println(x)
  }
}

多個(gè) goroutine 同步響應(yīng)

利用 close 廣播

func main() {
  c := make(chan struct{})
  for i := 0; i < 5; i++ {
    go do(c)
  }
  close(c)
}

func do(c <-chan struct{}) {
  // 會(huì)阻塞直到收到 close
  <-c
  fmt.Println("hello")
}

非阻塞的 select

select 本身是阻塞的,當(dāng)所有分支都不滿足就會(huì)一直阻塞,如果想不阻塞,那么一個(gè)什么都不干的 default 分支是最好的選擇

select {
case <-done:
  return
default:  
}

for{select{}} 終止

盡量不要用 break label 形式,而是把終止循環(huán)的條件放到 for 條件里來(lái)實(shí)現(xiàn)

for ok {
  select {
  case ch <- 0:
  case <-done:
    ok = false
  }
}

channel 特性

基礎(chǔ)特性

操作 值為 nil 的 channel 被關(guān)閉的 channel 正常的 channel
close panic panic 成功關(guān)閉
c<- 永遠(yuǎn)阻塞 panic 阻塞或成功發(fā)送
<-c 永遠(yuǎn)阻塞 永遠(yuǎn)不阻塞 阻塞或成功接收

happens-before 特性

  1. 無(wú)緩沖時(shí),接收 happens-before 發(fā)送
  2. 任何情況下,發(fā)送 happens-before 接收
  3. close happens-before 接收

參考

https://go101.org/article/channel.html
https://golang.org/doc/effective_go.html#channels

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Golang?Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式

    Golang?Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式

    在我們平常添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫(xiě)業(yè)務(wù)處理代碼了,但在此之前我們往往需要獲取請(qǐng)求參數(shù),本文就詳細(xì)的講解下gin獲取請(qǐng)求參數(shù)常見(jiàn)的幾種方式,需要的朋友可以參考下
    2024-02-02
  • Go語(yǔ)言dolphinscheduler任務(wù)調(diào)度處理

    Go語(yǔ)言dolphinscheduler任務(wù)調(diào)度處理

    這篇文章主要為大家介紹了Go語(yǔ)言dolphinscheduler任務(wù)調(diào)度處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 深入了解Golang官方container/heap用法

    深入了解Golang官方container/heap用法

    在?Golang?的標(biāo)準(zhǔn)庫(kù)?container?中,包含了幾種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn),其實(shí)是非常好的學(xué)習(xí)材料。今天我們就來(lái)看看?container/heap?的源碼,了解一下官方的同學(xué)是怎么設(shè)計(jì),我們作為開(kāi)發(fā)者又該如何使用
    2022-10-10
  • Go語(yǔ)言中的init函數(shù)特點(diǎn)及用法詳解

    Go語(yǔ)言中的init函數(shù)特點(diǎn)及用法詳解

    在Go語(yǔ)言中,init()函數(shù)是一種特殊的函數(shù),用于在程序啟動(dòng)時(shí)自動(dòng)執(zhí)行一次。它的存在為我們提供了一種機(jī)制,可以在程序啟動(dòng)時(shí)進(jìn)行一些必要的初始化操作,為程序的正常運(yùn)行做好準(zhǔn)備,在這篇文章中,我們將詳細(xì)探討init()函數(shù)的特點(diǎn)、用途和注意事項(xiàng)
    2023-06-06
  • 詳解Go語(yǔ)言中Goroutine退出機(jī)制的原理及使用

    詳解Go語(yǔ)言中Goroutine退出機(jī)制的原理及使用

    goroutine是Go語(yǔ)言提供的語(yǔ)言級(jí)別的輕量級(jí)線程,在我們需要使用并發(fā)時(shí),我們只需要通過(guò)?go?關(guān)鍵字來(lái)開(kāi)啟?goroutine?即可。本文就來(lái)詳細(xì)講講Goroutine退出機(jī)制的原理及使用,感興趣的可以了解一下
    2022-07-07
  • 詳解Go 結(jié)構(gòu)體格式化輸出

    詳解Go 結(jié)構(gòu)體格式化輸出

    這篇文章主要介紹了Go 結(jié)構(gòu)體格式化輸出的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)go語(yǔ)言,感興趣的朋友可以了解下
    2020-08-08
  • go語(yǔ)言中的udp協(xié)議及TCP通訊實(shí)現(xiàn)示例

    go語(yǔ)言中的udp協(xié)議及TCP通訊實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了go語(yǔ)言中的udp協(xié)議及TCP通訊的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go語(yǔ)言操作之nacos配置中心

    go語(yǔ)言操作之nacos配置中心

    這篇文章主要介紹了go語(yǔ)言操作之nacos配置中心,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • go語(yǔ)言題解LeetCode1299將每個(gè)元素替換為右側(cè)最大元素

    go語(yǔ)言題解LeetCode1299將每個(gè)元素替換為右側(cè)最大元素

    這篇文章主要為大家介紹了go語(yǔ)言LeetCode刷題1299將每個(gè)元素替換為右側(cè)最大元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn)

    Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn)

    本文主要介紹了Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

白沙| 永清县| 内黄县| 海丰县| 黔江区| 高青县| 昌黎县| 白城市| 四子王旗| 青田县| 措勤县| 巢湖市| 上虞市| 鄂伦春自治旗| 绵阳市| 富宁县| 永州市| 衡水市| 土默特右旗| 无为县| 壤塘县| 桐乡市| 民丰县| 望江县| 宿迁市| 晋宁县| 博爱县| 富锦市| 洞口县| 鹰潭市| 增城市| 柳江县| 三穗县| 图片| 大城县| 佛教| 上犹县| 嫩江县| 八宿县| 孟村| 怀来县|