免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

使用Golang怎么關閉channel

使用Golang怎么關閉channel?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

網站建設哪家好,找成都創新互聯公司!專注于網頁設計、網站建設、微信開發、重慶小程序開發、集團企業網站建設等服務項目。為回饋新老客戶創新互聯還提供了巴宜免費建站歡迎大家使用!

關于Go channel設計和規范的批評:

  • 在不能更改channel狀態的情況下,沒有簡單普遍的方式來檢查channel是否已經關閉了

  • 關閉已經關閉的channel會導致panic,所以在closer(關閉者)不知道channel是否已經關閉的情況下去關閉channel是很危險的

  • 發送值到已經關閉的channel會導致panic,所以如果sender(發送者)在不知道channel是否已經關閉的情況下去向channel發送值是很危險的

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

看如下代碼,在一段時間內,生產者可以不斷往 channel 寫入數據,消費者進行處理,一段時間后 channel 關閉了,這個時候如果還有數據往 channel 發送,程序就會報錯。

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

如何優雅關閉 channel

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

1._,ok := <- jobs

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

2.使用 select 方式

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

看完上述內容,你們掌握使用Golang怎么關閉channel的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!

分享名稱:使用Golang怎么關閉channel
本文URL:http://m.newbst.com/article0/jesgio.html

成都網站建設公司_創新互聯,為您提供商城網站動態網站品牌網站制作標簽優化定制網站建站公司

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

外貿網站制作