真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Golang中如何解決for-loop與goroutine的問題-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)Golang中如何解決for-loop與goroutine的問題的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

目前成都創(chuàng)新互聯(lián)已為上千多家的企業(yè)提供了網(wǎng)站建設、域名、網(wǎng)頁空間、網(wǎng)站托管維護、企業(yè)網(wǎng)站設計、河東網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

參見如下代碼:

for i := 0; i < len(rf.peers); i++ {
  DPrintf("i = %d", i)

  if i == rf.me {
   DPrintf("skipping myself #%d", rf.me)
   continue
  }

  go func() {
   DPrintf("len of rf.peers = %d", len(rf.peers))
   DPrintf("server #%d sending request vote to server %d", rf.me, i)
   reply := &RequestVoteReply{}
   ok := rf.sendRequestVote(i, args, reply)
   if ok && reply.VoteGranted && reply.Term == rf.currentTerm {
    rf.voteCount++
    if rf.voteCount > len(rf.peers)/2 {
     rf.winElectionCh <- true
    }
   }
  }()
}

其中,peers切片的長度為3,因此最高下標為2,在非并行編程中代碼中的for-loop應該是很直觀的,我當時并沒有意識到有什么問題??墒窃谡{(diào)試過程中,一直在報 index out of bounds 錯誤。調(diào)試信息顯示i的值為3,當時就一直想不明白循環(huán)條件明明是 i < 2,怎么會變成3呢。

分析

雖然不明白發(fā)生了什么,但知道應該是循環(huán)中引入的 goroutine 導致的。經(jīng)過Google,發(fā)現(xiàn)Go的wiki中就有一個頁面 Common Mistake - Using goroutines on loop iterator variables 專門提到了這個問題,看來真的是很 common 啊,笑哭~

初學者經(jīng)常會使用如下代碼來并行處理數(shù)據(jù):

for val := range values {
 go val.MyMethod()
}

或者使用閉包(closure):

for val := range values {
 go func() {
  fmt.Println(val)
 }()
}

這里的問題在于 val 實際上是一個遍歷了切片中所有數(shù)據(jù)的單一變量。由于閉包只是綁定到這個 val 變量上,因此極有可能上面的代碼的運行結(jié)果是所有 goroutine 都輸出了切片的最后一個元素。這是因為很有可能當 for-loop 執(zhí)行完之后 goroutine 才開始執(zhí)行,這個時候 val 的值指向切片中最后一個元素。

The val variable in the above loops is actually a single variable that takes on the value of each slice element. Because the closures are all only bound to that one variable, there is a very good chance that when you run this code you will see the last element printed for every iteration instead of each value in sequence, because the goroutines will probably not begin executing until after the loop.

解決方法

以上代碼正確的寫法為:

for val := range values {
 go func(val interface{}) {
  fmt.Println(val)
 }(val)
}

在這里將 val 作為一個參數(shù)傳入 goroutine 中,每個 val 都會被獨立計算并保存到 goroutine 的棧中,從而得到預期的結(jié)果。

另一種方法是在循環(huán)內(nèi)定義新的變量,由于在循環(huán)內(nèi)定義的變量在循環(huán)遍歷的過程中是不共享的,因此也可以達到同樣的效果:

for i := range valslice {
 val := valslice[i]
 go func() {
  fmt.Println(val)
 }()
}

對于文章開頭提到的那個問題,最簡單的解決方案就是在循環(huán)內(nèi)加一個臨時變量,并將后面 goroutine 內(nèi)的 i 都替換為這個臨時變量即可:

server := i

感謝各位的閱讀!關(guān)于“Golang中如何解決for-loop與goroutine的問題”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


本文題目:Golang中如何解決for-loop與goroutine的問題-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://weahome.cn/article/ddcsps.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部