1. ホーム
  2. go

[解決済み] time.Sleepを使わずにすべてのゴルーチンが終了するのを待つには?

2022-07-03 21:29:02

質問

このコードは、呼び出された実行ファイルとして、同じフォルダ内のすべてのxmlファイルを選択し、コールバックメソッドでそれぞれの結果に対して非同期に処理を適用します(以下の例では、ファイル名のみが出力されます)。

mainメソッドを終了させないためにsleepメソッドを使用しないようにするにはどうしたらよいですか。チャネル (結果を同期させるために必要なものだと仮定します) について私の頭を包むことに問題があるので、どのような助けでも感謝します!

package main

import (
    "fmt"
    "io/ioutil"
    "path"
    "path/filepath"
    "os"
    "runtime"
    "time"
)

func eachFile(extension string, callback func(file string)) {
    exeDir := filepath.Dir(os.Args[0])
    files, _ := ioutil.ReadDir(exeDir)
    for _, f := range files {
            fileName := f.Name()
            if extension == path.Ext(fileName) {
                go callback(fileName)
            }
    }
}


func main() {
    maxProcs := runtime.NumCPU()
    runtime.GOMAXPROCS(maxProcs)

    eachFile(".xml", func(fileName string) {
                // Custom logic goes in here
                fmt.Println(fileName)
            })

    // This is what i want to get rid of
    time.Sleep(100 * time.Millisecond)
}

どのように解決するのですか?

あなたは sync.WaitGroup . リンク先の例を引用します。

package main

import (
        "net/http"
        "sync"
)

func main() {
        var wg sync.WaitGroup
        var urls = []string{
                "http://www.golang.org/",
                "http://www.google.com/",
                "http://www.somestupidname.com/",
        }
        for _, url := range urls {
                // Increment the WaitGroup counter.
                wg.Add(1)
                // Launch a goroutine to fetch the URL.
                go func(url string) {
                        // Decrement the counter when the goroutine completes.
                        defer wg.Done()
                        // Fetch the URL.
                        http.Get(url)
                }(url)
        }
        // Wait for all HTTP fetches to complete.
        wg.Wait()
}