Как ждать, пока все goroutines закончат, не используя time.Sleep?

Этот код выбирает все XML-файлы в той же папке, что и вызываемый исполняемый файл, и асинхронно применяет обработку к каждому результату в методе обратного вызова (в приведенном ниже примере выводится только имя файла).

Как мне избежать использования метода сна, чтобы предотвратить выход основного метода? У меня проблемы с намоткой на каналы (полагаю, чтоs, что требуется, чтобы синхронизировать результаты), поэтому любая помощь приветствуется!

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)
}

Ответы на вопрос(4)

Ваш ответ на вопрос