Golang循環中調用go func參數異常分析


項目中,需要循環調用API服務器列表,在循環中使用go func創建協程時遇到了參數失靈的現象.
具體代碼如下所示:

	for _, apiServerAddr := range apiServerAddrList {
		go func() {
			callApiServer(apiServerAddr)
		}()
	}

在運行過程中,發現callApiServer中參數apiServerAddr實際值一直是apiServerAddrList 的最后一個元素值.
將代碼修改為如下形式,則每一個創建的協程中apiServerAddr 則是循環的數值.

	for _, apiServerAddr := range apiServerAddrList {
		go callApiServer(apiServerAddr)
	}

查詢stackoverflow,發現原因如下:

  • 循環中,go callApiServer(apiServerAddr)創建的協程中,使用的apiServerAddr是其數值;
  • 循環中,go func(){callApiServer(apiServerAddr)}()創建的協程中,使用的apiServerAddr是其引用,在循環執行至一定次數后,Golang調度器調度協程,協程獲取當前時刻apiServerAddr的數值,此時就會產生錯誤.

golang的閉包,能夠從創建它的作用域中獲取變量,且獲取的是變量的引用而非變量的副本.

go func修改為如下格式,能夠正確調用:

	for _, apiServerAddr := range apiServerAddrList {
		go func(addr string) {
			callApiServer(addr )
		}(apiServerAddr )
	}

PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!
程序員打怪之路


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM