濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解

golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解

熱門標(biāo)簽:浙江高頻外呼系統(tǒng)多少錢一個(gè)月 濱州自動(dòng)電銷機(jī)器人排名 釘釘有地圖標(biāo)注功能嗎 汕頭小型外呼系統(tǒng) 鄭州亮點(diǎn)科技用的什么外呼系統(tǒng) 黃岡人工智能電銷機(jī)器人哪個(gè)好 惠州電銷防封電話卡 建造者2地圖標(biāo)注 阿里云ai電話機(jī)器人

前言

for循環(huán)是Go語(yǔ)言唯一的循環(huán)結(jié)構(gòu),最近在做一個(gè)基于RabbitMQ的應(yīng)用,由于官方的qos沒(méi)有g(shù)olang的版本,所以出了一點(diǎn)問(wèn)題。

問(wèn)題代碼如下:

_, 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)
 }

發(fā)現(xiàn)消費(fèi)到10條消息,進(jìn)程就退出了,但是exit code為0,表示系統(tǒng)是正常退出,由于做了日志記錄可以確定消費(fèi)了10條,所以初步確定是qos相關(guān)問(wèn)題。

排查過(guò)程

  • 首先是把d的tag打印出來(lái),發(fā)現(xiàn)全部是一樣的,可以確定是重復(fù)的一條消息
  • 一開(kāi)始想到可能是經(jīng)典的go協(xié)程執(zhí)行在for循環(huán)結(jié)束以后導(dǎo)致的,但是看我的代碼不屬于這種情況,有使用m保證每一條消息都是不同循環(huán)傳入的。所以判斷可能是for循環(huán)的傳遞問(wèn)題。
  • 確定方向之后開(kāi)始寫了一個(gè)測(cè)試項(xiàng)目用來(lái)驗(yàn)證我的想法是否正確。

測(cè)試代碼

package main
import "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)
 }
}

執(zhí)行輸出

0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008

到這里才煥然大悟,for循環(huán)中,如果循環(huán)變量不是指針,那么每次的變量是同一個(gè),不過(guò)值變了。,所以上例中的RabbitMQ go協(xié)程消費(fèi)消息那里,需要直接傳遞值而不是指針,經(jīng)過(guò)測(cè)試之后發(fā)現(xiàn),問(wèn)題確實(shí)解決了。

題外話

測(cè)試代碼那里,如果不close掉channel是會(huì)發(fā)生死鎖的,原因是 當(dāng)for循環(huán)讀完channel的10個(gè)值之后會(huì)繼續(xù)嘗試讀取下一個(gè),而由于channel為空又沒(méi)關(guān)閉,會(huì)一直阻塞形成死鎖

TOOD

研究RabbitMQ Consumer部分的源碼來(lái)看看消費(fèi)channel被關(guān)閉的問(wèn)題。

總結(jié)

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

您可能感興趣的文章:
  • 基于golang channel實(shí)現(xiàn)的輕量級(jí)異步任務(wù)分發(fā)器示例代碼
  • golang實(shí)現(xiàn)基于channel的通用連接池詳解
  • Golang優(yōu)雅關(guān)閉channel的方法示例
  • golang中單向channel的語(yǔ)法介紹
  • golang判斷chan channel是否關(guān)閉的方法
  • Golang中channel使用的一些小技巧
  • Golang中channel的原理解讀(推薦)

標(biāo)簽:泰安 瀘州 東營(yíng) 阿壩 駐馬店 晉中 滄州 昭通

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解》,本文關(guān)鍵詞  golang,中,for,循環(huán),遍歷,channel,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    忻州市| 宁蒗| 宝山区| 龙里县| 股票| 贵德县| 浠水县| 宁阳县| 英吉沙县| 五莲县| 敦化市| 全椒县| 清水河县| 岱山县| 乌海市| 当涂县| 唐海县| 安远县| 天镇县| 荆州市| 中牟县| 神池县| 海伦市| 汉源县| 泽库县| 清涧县| 育儿| 收藏| 红河县| 九台市| 江阴市| 邓州市| 泰和县| 乌审旗| 施甸县| 滦南县| 虞城县| 观塘区| 石林| 浦东新区| 三门县|