亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

編寫此代碼的更好的慣用方式?

編寫此代碼的更好的慣用方式?

Go
慕田峪7331174 2021-06-03 14:50:10
玩轉 go,我把這段代碼放在一起:package mainimport "fmt"const N = 10func main() {    ch := make(chan int, N)    done := make(chan bool)    for i := 0; i < N; i++ {        go (func(n int, ch chan int, done chan bool) {            for i := 0; i < N; i++ {                ch <- n*N + i            }            done <- true        })(i, ch, done)    }    numDone := 0    for numDone < N {        select {        case i := <-ch:            fmt.Println(i)        case <-done:            numDone++        }    }    for {        select {        case i := <-ch:            fmt.Println(i)        default:            return        }    }}基本上我有 N 個頻道在做一些工作并在同一個頻道上報告——我想知道所有頻道什么時候完成。所以我有另一個done通道,每個工作程序 goroutine 都會在其上發送一條消息(消息無關緊要),這會導致 main 將該線程計為已完成。當計數達到 N 時,我們實際上就完成了。這是“好”嗎?有沒有更慣用的方式來做到這一點?編輯:澄清一下,我很懷疑,因為done通道似乎正在做一個通道關閉似乎是為了的工作,但當然我實際上不能在任何 goroutine 中關閉通道,因為所有的例程共享同一個通道. 所以我done用來模擬一個執行某種“緩沖關閉”的通道。編輯2:原始代碼并沒有真正起作用,因為有時在done它剛剛放入的 int 之前讀取來自例程的信號ch。需要一個“清理”循環。
查看完整描述

3 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

這里是sync.WaitGroup的慣用用法,供大家學習

package main


import (

    "fmt"

    "sync"

)


const N = 10


func main() {

    ch := make(chan int, N)

    var wg sync.WaitGroup

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

        wg.Add(1)

        go func(n int) {

            defer wg.Done()

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

                ch <- n*N + i

            }

        }(i)

    }

    go func() {

        wg.Wait()

        close(ch)

    }()

    for i := range ch {

        fmt.Println(i)

    }

}

注意兩個go例程定義中閉包的使用,注意第二條go語句等待所有例程完成,然后關閉通道,所以range可以使用。


查看完整回答
反對 回復 2021-06-07
  • 3 回答
  • 0 關注
  • 263 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號