У меня есть этот код go, который обходит дерево файлов каталогов и создает хэши MD5 для каждого файла в нем и записывает результат в выходной файл.
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"os"
"path/filepath"
"sync"
)
func main() {
filePath := os.Args[1]
output := os.Args[2]
wg := &sync.WaitGroup{}
err := filepath.Walk(filePath, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
wg.Add(1)
go func(path string) {
md5Sum, _ := md5File(path)
if err := writeToFile(path, md5Sum, output); err != nil {
panic(err)
}
wg.Done()
}(path)
}
return nil
})
if err != nil {
panic(err)
}
wg.Wait()
}
func md5File(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
hash := md5.New()
if _, err := io.Copy(hash, file); err != nil {
return "", err
}
checksum := hash.Sum(nil)
return string(hex.EncodeToString(checksum)), nil
}
func writeToFile(filePath, md5sum, output string) error {
file, err := os.OpenFile(output, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
file.WriteString(fmt.Sprintf("%s %s\n", md5sum, filePath))
return file.Sync()
}
Насколько я понимаю, когда-нибудь при записи в выходной файл он обязательно попадет в состояние состязания, но этого не произойдет.Я имею в виду, что я выполнял этот код бесчисленное количество раз, никогда не сталкиваясь с какими-либо проблемами.Он даже дает один и тот же результат каждый раз.
Почему это так?Я что-то упускаю?
ОБНОВЛЕНИЕ: Когда я говорю, что это связано с состоянием гонки, я имею в виду, что при запуске нескольких подпрограмм возможно, что более одной подпрограммы захочет записать в файлв то же время.