亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Golang優(yōu)雅關(guān)閉channel的方法示例

 更新時間:2017年11月19日 09:52:39   作者:小談  
Goroutine和channel是Go在“并發(fā)”方面兩個核心feature,下面這篇文章主要給大家介紹了關(guān)于Golang如何優(yōu)雅關(guān)閉channel的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考解決,下面來一起看看吧。

前言

最近使用go開發(fā)后端服務(wù),服務(wù)關(guān)閉需要保證channel中的數(shù)據(jù)都被讀取完,理由很簡單,在收到系統(tǒng)的中斷信號后,系統(tǒng)需要做收尾工作,保證channel的數(shù)據(jù)都要被處理掉,然后才可以關(guān)閉系統(tǒng)。但實(shí)現(xiàn)起來沒那么簡單,下面來一起看看詳細(xì)的介紹吧。

關(guān)于Go channel設(shè)計(jì)和規(guī)范的批評:

  • 在不能更改channel狀態(tài)的情況下,沒有簡單普遍的方式來檢查channel是否已經(jīng)關(guān)閉了
  • 關(guān)閉已經(jīng)關(guān)閉的channel會導(dǎo)致panic,所以在closer(關(guān)閉者)不知道channel是否已經(jīng)關(guān)閉的情況下去關(guān)閉channel是很危險的
  • 發(fā)送值到已經(jīng)關(guān)閉的channel會導(dǎo)致panic,所以如果sender(發(fā)送者)在不知道channel是否已經(jīng)關(guān)閉的情況下去向channel發(fā)送值是很危險的

所以Golang 內(nèi)建的 close 方法可以關(guān)閉 channel,如果往已經(jīng)關(guān)閉的 channel 發(fā)送數(shù)據(jù),則會報錯:panic: close of closed channel.

看如下代碼,在一段時間內(nèi),生產(chǎn)者可以不斷往 channel 寫入數(shù)據(jù),消費(fèi)者進(jìn)行處理,一段時間后 channel 關(guān)閉了,這個時候如果還有數(shù)據(jù)往 channel 發(fā)送,程序就會報錯。

package main
 
import (
 "fmt"
 "sync"
 "time"
)
 
func main() {
 jobs := make(chan int)
 var wg sync.WaitGroup
 go func() {
 time.Sleep(time.Second * 3)
 close(jobs)
 }()
 go func() {
 for i := 0; ; i++ {
 jobs <- i
 fmt.Println("produce:", i)
 }
 }()
 wg.Add(1)
 go func() {
 defer wg.Done()
 for i := range jobs {
 fmt.Println("consume:", i)
 }
 }()
 wg.Wait()
}

多運(yùn)行幾次出錯的概率會比較大:

produce: 33334
consume: 33334
consume: 33335
produce: 33335
produce: 33336
consume: 33336
consume: 33337
produce: 33337
produce: 33338
consume: 33338
consume: 33339
produce: 33339
produce: 33340
consume: 33340
panic: send on closed channel
 
goroutine 19 [running]:
panic(0x49b660, 0xc042410bb0)
  C:/Go/src/runtime/panic.go:500 +0x1af
main.main.func2(0xc04203a180)
  C:/Users/tanteng/Go/src/examples/channel_close.go:18 +0x6b
created by main.main
  C:/Users/tanteng/Go/src/examples/channel_close.go:21 +0xb8
exit status 2

如何優(yōu)雅關(guān)閉 channel

那么在往通道發(fā)數(shù)據(jù)前如何判斷通道是否關(guān)閉呢?

1._,ok := <- jobs

此時如果 channel 關(guān)閉,ok 值為 false,如果 channel 沒有關(guān)閉,則會漏掉一個 jobs

2.使用 select 方式

再創(chuàng)建一個 channel,叫做 timeout,如果超時往這個 channel 發(fā)送 true,在生產(chǎn)者發(fā)送數(shù)據(jù)給 jobs 的 channel,用 select 監(jiān)聽 timeout,如果超時則關(guān)閉 jobs 的 channel.

完整代碼如下:

package main
 
import (
 "fmt"
 "sync"
 "time"
)
 
func main() {
 jobs := make(chan int)
 timeout := make(chan bool)
 var wg sync.WaitGroup
 go func() {
 time.Sleep(time.Second * 3)
 timeout <- true
 }()
 go func() {
 for i := 0; ; i++ {
 select {
 case <-timeout:
 close(jobs)
 return
 
 default:
 jobs <- i
 fmt.Println("produce:", i)
 }
 }
 }()
 wg.Add(1)
 go func() {
 defer wg.Done()
 for i := range jobs {
 fmt.Println("consume:", i)
 }
 }()
 wg.Wait()
}

這樣就可以保證不會往已經(jīng)關(guān)閉的 channel 中發(fā)送數(shù)據(jù)了。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 詳解如何利用GORM實(shí)現(xiàn)MySQL事務(wù)

    詳解如何利用GORM實(shí)現(xiàn)MySQL事務(wù)

    為了確保數(shù)據(jù)一致性,在項(xiàng)目中會經(jīng)常用到事務(wù)處理,對于MySQL事務(wù)相信大家應(yīng)該都不陌生。這篇文章主要總結(jié)一下在Go語言中Gorm是如何實(shí)現(xiàn)事務(wù)的;感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助
    2022-09-09
  • 詳解如何用Golang處理每分鐘100萬個請求

    詳解如何用Golang處理每分鐘100萬個請求

    在項(xiàng)目開發(fā)中,我們常常會遇到處理來自數(shù)百萬個端點(diǎn)的大量POST請求,本文主要介紹了Golang實(shí)現(xiàn)處理每分鐘100萬個請求的方法,希望對大家有所幫助
    2023-04-04
  • GoFrame框架gset使用對比PHP?Java?Redis優(yōu)勢

    GoFrame框架gset使用對比PHP?Java?Redis優(yōu)勢

    這篇文章主要為大家介紹了GoFrame框架gset對比PHP?Java?Redis的使用優(yōu)勢詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • GO 語言運(yùn)行環(huán)境的基礎(chǔ)知識

    GO 語言運(yùn)行環(huán)境的基礎(chǔ)知識

    這篇文章主要介紹了GO 語言運(yùn)行環(huán)境的基礎(chǔ)知識的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • golang跳轉(zhuǎn)語句goto,break,continue的使用及區(qū)別說明

    golang跳轉(zhuǎn)語句goto,break,continue的使用及區(qū)別說明

    這篇文章主要介紹了golang跳轉(zhuǎn)語句goto,break,continue的使用及區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言編程入門超級指南

    Go語言編程入門超級指南

    這篇文章主要介紹了Go語言編程的入門指南,包括對Go的變量及函數(shù)的基本介紹,需要的朋友可以參考下
    2016-01-01
  • 基于golang中container/list包的用法說明

    基于golang中container/list包的用法說明

    這篇文章主要介紹了基于golang中container/list包的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言學(xué)習(xí)技巧之如何合理使用Pool

    Go語言學(xué)習(xí)技巧之如何合理使用Pool

    這篇文章主要給大家介紹了關(guān)于Go語言學(xué)習(xí)技巧之如何合理使用Pool的相關(guān)資料,Pool用于存儲那些被分配了但是沒有被使用,而未來可能會使用的值,以減小垃圾回收的壓力。文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • 詳解如何熱重啟golang服務(wù)器

    詳解如何熱重啟golang服務(wù)器

    這篇文章主要介紹了詳解如何熱重啟golang服務(wù)器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • go語言區(qū)塊鏈學(xué)習(xí)調(diào)用以太坊

    go語言區(qū)塊鏈學(xué)習(xí)調(diào)用以太坊

    這篇文章主要為大家介紹了go語言區(qū)塊鏈學(xué)習(xí)如何調(diào)用以太坊的示例實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10

最新評論