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

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

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

前言

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

關于Go channel設計和規(guī)范的批評:

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

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

看如下代碼,在一段時間內,生產者可以不斷往 channel 寫入數據,消費者進行處理,一段時間后 channel 關閉了,這個時候如果還有數據往 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()
}

多運行幾次出錯的概率會比較大:

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)雅關閉 channel

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

1._,ok := <- jobs

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

2.使用 select 方式

再創(chuàng)建一個 channel,叫做 timeout,如果超時往這個 channel 發(fā)送 true,在生產者發(fā)送數據給 jobs 的 channel,用 select 監(jiān)聽 timeout,如果超時則關閉 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()
}

這樣就可以保證不會往已經關閉的 channel 中發(fā)送數據了。

總結

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

相關文章

  • 詳解如何利用GORM實現MySQL事務

    詳解如何利用GORM實現MySQL事務

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

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

    在項目開發(fā)中,我們常常會遇到處理來自數百萬個端點的大量POST請求,本文主要介紹了Golang實現處理每分鐘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)勢詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • GO 語言運行環(huán)境的基礎知識

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

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

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

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

    Go語言編程入門超級指南

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

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

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

    Go語言學習技巧之如何合理使用Pool

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

    詳解如何熱重啟golang服務器

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

    go語言區(qū)塊鏈學習調用以太坊

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

最新評論