普通网友 2019-05-08 10:28
浏览 50
已采纳

为什么此代码未达到竞争条件?

I have this go code which walks a directory file tree and produces MD5 hashes of every file in it and writes the result in an output file.

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
", md5sum, filePath))

    return file.Sync()
}

From my understanding it is bound to run into a race condition sometime upon writing to the output file but it never does. I mean I have executed this code countless times never facing any issues. It even produces the same result every time.

Why is that? Am I missing something?

UPDATE: When I say it is bound to face a race condition I mean when running multiple goroutines it is possible for more than one goroutine to want to write to file at the same time.

  • 写回答

1条回答 默认 最新

  • dontoften8899 2019-05-08 10:43
    关注

    When I say it is bound to face a race condition I mean when running multiple goroutines it is possible for more than one goroutine to want to write to file at the same time.

    It is not a problem to open a file multiple times. And since you explicitly use O_APPEND the writes don't interact badly with each other. To cite from man open:

    O_APPEND ...
    Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Android Studio中如何把H5逻辑放在Assets 文件夹中以实现将h5代码打包为apk
  • ¥15 使用小程序wx.createWebAudioContext()开发节拍器
  • ¥15 关于#爬虫#的问题:请问HMDB代谢物爬虫的那个工具可以提供一下吗
  • ¥15 vue3+electron打包获取本地视频属性,文件夹里面有ffprobe.exe 文件还会报错这是什么原因呢?
  • ¥20 用51单片机控制急停。
  • ¥15 孟德尔随机化结果不一致
  • ¥15 在使用pyecharts时出现问题
  • ¥15 深度学习残差模块模型
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算