第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無限for循環(huán)內的goroutine。這是一個好習慣嗎?

無限for循環(huán)內的goroutine。這是一個好習慣嗎?

Go
RISEBY 2022-07-11 15:45:54
所以我正在編寫一段代碼:// Mainfor {    c := make(chan string)    data := make(map[string]string)    go doStuff(data,c)    fmt.Println(<-c)    time.Sleep(2*time.Second)}// doStufffunc doStuff(d map[string]string,ch chan string){    defer close(ch)    //Code to make changes to passed data    ch <-"changes made"}它的作用是將映射和通道傳遞給goroutine,在其中對映射進行了一些更改,它將發(fā)送消息,并且在主程序中它將打印并等待另一個修改消息,并且間隔為處理傳遞給 goroutine 的數(shù)據(jù)后,直到鍵盤中斷或某些邏輯 2 秒。我在某個地方覺得這不是有效的方法。所以我的問題是在無限循環(huán)中放置一個 goroutine 是否可以,或者有沒有更有效的方法來做到這一點?
查看完整描述

1 回答

?
白衣非少年

TA貢獻1155條經驗 獲得超0個贊

無限循環(huán)本身并沒有錯。當循環(huán)退出條件需要太多命令才能輕松放入 for 條件時,我經常使用 for { ... } 構造。


根據(jù)我的$GOPATH/src/github.com/目錄,這顯然是一個非常不完整的樣本集,我看到了數(shù)百種超出我自己的這樣的用途。github.com/docker/docker僅此一項似乎就使用了 454 個這樣的無限循環(huán)。


不太合適的是在循環(huán)中創(chuàng)建一個只傳遞一個值的通道的想法。如果你的 goroutine 總是只返回一個值,那么這個返回值的存在就足以表明 goroutine 已經完成。盡可能重復使用通道,如果您想稍后發(fā)送更多數(shù)據(jù),請不要關閉它們。


顯然,在您的情況下,goroutine 無論如何都是毫無意義的,僅用于教育目的。但是考慮一下,如果你愿意的話:


package main


import (

  "log"

)


func doStuff(datachan <-chan map[string]string, reschan chan<- int) {

  for {

    data, ok := <-datachan

    if !ok {

      log.Print("Channel closed.")

      break

    }

    log.Printf("Data had %d length: %+v", len(data), data)

    reschan<-len(data)

  }

  return

}


const workers = 3


func main() {

  var datachan = make(chan map[string]string)

  var reschan = make(chan int)

  var inflight = 0

  var inputs = []map[string]string {

    map[string]string{ "hi": "world" },

    map[string]string{ "bye": "space", "including": "moon" },

    map[string]string{ "bye": "space", "including": "moon" },

    map[string]string{ },

    map[string]string{ },

  }

  // an inline funciton definition can change inflight within main()'s scope

  processResults := func (res int) {

    log.Printf("Main function got result %d", res)

    inflight--

  }

  // start some workers

  for i := 0; i < workers; i++{

    go doStuff(datachan, reschan)

  }

  for _, data := range inputs {

      //Select allows reading from reschan if datachan is not available for

      // writing, thus freeing up a worker to read from datachan next loop

      written := false

      for written  != true {

        select {

          case res := <-reschan:

            processResults(res)

          case datachan <- data:

            inflight++

            written = true

        }

      }

  }

  close(datachan)

  for inflight > 0 {

    processResults(<-reschan)

  }

}


輸出:


2020/10/31 13:15:08 Data had 1 length: map[hi:world]

2020/10/31 13:15:08 Main function got result 1

2020/10/31 13:15:08 Data had 0 length: map[]

2020/10/31 13:15:08 Main function got result 0

2020/10/31 13:15:08 Data had 0 length: map[]

2020/10/31 13:15:08 Channel closed.

2020/10/31 13:15:08 Main function got result 0

2020/10/31 13:15:08 Data had 2 length: map[bye:space including:moon]

2020/10/31 13:15:08 Channel closed.

2020/10/31 13:15:08 Main function got result 2

2020/10/31 13:15:08 Data had 2 length: map[bye:space including:moon]

2020/10/31 13:15:08 Channel closed.

2020/10/31 13:15:08 Main function got result 2

for {在這里,我添加了一些結構來說明和的一些更常見的用法close(chan)。


我在工作goroutines 中使用了一個潛在的無限循環(huán),其中有 3 個(故意創(chuàng)建的比使用的多)。我數(shù)了數(shù)我給頻道寫了多少次,以確保我閱讀了每一個回復。當主 goroutine 結束時,所有其他 goroutine 都會被毫不客氣地殺死,所以我要確保讓它們完成。計算結果是一種簡單的方法。


我還演示了正確使用close(chan). 雖然在使用后關閉通道(例如您所做的)是不正確的,但通常沒有必要這樣做,因為在所有對它們的引用無論如何都消失后,打開的通道將被垃圾收集。( https://stackoverflow.com/questions/8593645/is-it-ok-to-leave-a-channel-open#:~:text=It's%20OK%20to%20leave%20a,that%20no%20more% 20data%20 關注。)


close(chan)通常用于告訴頻道閱讀器該頻道上沒有更多數(shù)據(jù)可用。


    data, ok := <-datachan

第二個值,一個布爾值,將告訴我們是否讀取data或通道實際上已關閉和耗盡。所以這是確保我們已經處理所有通道的接收器部分。


因為我使用select,這段代碼可以處理inputs任意長度的,帶有一組靜態(tài)工作人員。這些通道都沒有緩沖 - 讀者必須在閱讀才能讓作者寫入。因此,在嘗試向該閱讀器發(fā)送另一個數(shù)據(jù)輸入之前,我需要確保從工作人員那里收到任何結果。使用select使這變得微不足道:操作在首先準備好的任何通道上成功(如果兩個通道都準備好,則隨機選擇一個選項 - 在這種情況下完美運行)。


for {,close(chan)和select, 總之,在向 goroutine worker bools 發(fā)送未知數(shù)量的輸入時,它們可以很好地協(xié)同工作。


一些最后的筆記。在現(xiàn)實世界中,通常會使用https://gobyexample.com/waitgroups而不是手動實現(xiàn)這一切。這個概念大體上是相同的,但它更少跟蹤事物并導致更清晰的代碼。我自己實現(xiàn)了它,所以概念很清楚。


最后,你會注意到在程序結束之前無法保證工作 goroutines 看到關閉的通道。實際上,從技術上講,可能不會從所有 goroutine 中記錄“關閉通道”消息。但是使用inflight計數(shù)器確保我得到了他們的結果,即使他們沒有機會觀察通道的關閉。當應用程序隨著時間的推移繼續(xù)運行多批工作人員時,關閉通道和退出工作人員更有意義 - 如果我們沒有通知他們關閉,但后來創(chuàng)建了更多工作人員,這將導致內存泄漏,就像那些工作人員一樣繼續(xù)等待永遠不會到來的輸入。或者,對多批請求使用同一組工作人員并不罕見。


查看完整回答
反對 回復 2022-07-11
  • 1 回答
  • 0 關注
  • 195 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號