国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Golang > 正文

golang中for循環遍歷channel時需要注意的問題詳解

2020-04-01 18:57:41
字體:
來源:轉載
供稿:網友

前言

for循環是Go語言唯一的循環結構,最近在做一個基于RabbitMQ的應用,由于官方的qos沒有golang/299797.html">golang/304362.html">golang的版本,所以出了一點問題。

問題代碼如下:

_, ch, err := component.NewRabbitMQ()if err != nil { panic(err)}if err := ch.Qos(10, 0, true); err != nil { panic(err)}msgs, err := ch.Consume("push", "", false, false, false, false, nil)if err != nil { panic(err)}for m := range msgs { go func(d *amqp.Delivery) {   defer func() { d.Ack(false) }   // 處理消息  }(&m) }

發現消費到10條消息,進程就退出了,但是exit code為0,表示系統是正常退出,由于做了日志記錄可以確定消費了10條,所以初步確定是qos相關問題。

排查過程

  • 首先是把d的tag打印出來,發現全部是一樣的,可以確定是重復的一條消息
  • 一開始想到可能是經典的go協程執行在for循環結束以后導致的,但是看我的代碼不屬于這種情況,有使用&m保證每一條消息都是不同循環傳入的。所以判斷可能是for循環的傳遞問題。
  • 確定方向之后開始寫了一個測試項目用來驗證我的想法是否正確。

測試代碼

package mainimport "fmt"func main() { ch := make(chan int, 10) for i := 0; i < 10; i++ { ch <- i } close(ch) for v := range ch { fmt.Println(&v) }}

執行輸出

0xc4200860080xc4200860080xc4200860080xc4200860080xc4200860080xc4200860080xc4200860080xc4200860080xc4200860080xc420086008

到這里才煥然大悟,for循環中,如果循環變量不是指針,那么每次的變量是同一個,不過值變了。,所以上例中的RabbitMQ go協程消費消息那里,需要直接傳遞值而不是指針,經過測試之后發現,問題確實解決了。

題外話

測試代碼那里,如果不close掉channel是會發生死鎖的,原因是 當for循環讀完channel的10個值之后會繼續嘗試讀取下一個,而由于channel為空又沒關閉,會一直阻塞形成死鎖

TOOD

研究RabbitMQ Consumer部分的源碼來看看消費channel被關閉的問題。

總結

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 华容县| 二连浩特市| 湖北省| 葫芦岛市| 密云县| 宽城| 延边| 松阳县| 会泽县| 崇仁县| 阳山县| 福贡县| 探索| 阿巴嘎旗| 桦南县| 大庆市| 北辰区| 柯坪县| 壤塘县| 阳信县| 阿荣旗| 崇仁县| 紫金县| 达拉特旗| 滦南县| 葫芦岛市| 黎川县| 乐平市| 临武县| 简阳市| 崇阳县| 乐至县| 肇庆市| 时尚| 沙雅县| 抚州市| 双流县| 通渭县| 高台县| 乐安县| 达日县|