Golang并发僵局

时间:2016-06-16 14:30:54

标签: go concurrency deadlock

任何人都可以帮我确定为什么我在Go代码结束时遇到死锁错误我写的?程序实际运行正常,但我遇到了死锁错误。我是编写并发代码的新手,所以非常感谢任何帮助。我省略了一些我不知道的问题,只是为了让它更快阅读。

func MoveWorksheets(worksheetList []string) {

var wg sync.WaitGroup

for _, worksheet := range worksheetList {

    wg.Add(1)

    go MoveFile(src, dst, wg)

    }

    wg.Wait()
}

func MoveFile(src, dst string, wg sync.WaitGroup) (err error) {

    defer wg.Done()

    sfi, err := os.Stat(src)
    if err != nil {
        return
    }
    if !sfi.Mode().IsRegular() {
        // cannot copy non-regular files (e.g., directories,
        // symlinks, devices, etc.)
        return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String())
    }
    dfi, err := os.Stat(dst)
    if err != nil {
        if !os.IsNotExist(err) {
            return
        }
    } else {
        if !(dfi.Mode().IsRegular()) {
            return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String())
        }
        if os.SameFile(sfi, dfi) {
            return
        }
    }
    /*if err = os.Link(src, dst); err == nil {
        return
    }*/
    err = MoveFileContents(src, dst)
    return
}

func MoveFileContents(src, dst string) (err error) {

    merr := os.Rename(src, dst)

    if merr != nil {
        log.Fatal(merr)
    }

    return
}

2 个答案:

答案 0 :(得分:1)

wg正在获取Wait()的副本,因此您在不同的Done()上呼叫WaitGroupclass Car { public doors; public color; public seats; } 。尝试将其作为指针传递。

答案 1 :(得分:0)

尝试传递wg变量的引用,在您的代码MoveFile函数中获取自己的WaitGroup副本。这就是它造成僵局的原因。

   func MoveWorksheets(worksheetList []string) {

        var wg sync.WaitGroup

        for _, worksheet := range worksheetList {

          wg.Add(1)

          go MoveFile(src, dst, &wg)

        }

        wg.Wait()
    }

    func MoveFile(src, dst string, wg *sync.WaitGroup) (err error) {

        defer wg.Done()

        sfi, err := os.Stat(src)
        if err != nil {
            return
        }
        if !sfi.Mode().IsRegular() {
            // cannot copy non-regular files (e.g., directories,
            // symlinks, devices, etc.)
            return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String())
        }
        dfi, err := os.Stat(dst)
        if err != nil {
            if !os.IsNotExist(err) {
                return
            }
        } else {
            if !(dfi.Mode().IsRegular()) {
                return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String())
            }
            if os.SameFile(sfi, dfi) {
                return
            }
        }
        /*if err = os.Link(src, dst); err == nil {
            return
        }*/
        err = MoveFileContents(src, dst)
        return
    }

    func MoveFileContents(src, dst string) (err error) {

        merr := os.Rename(src, dst)

        if merr != nil {
            log.Fatal(merr)
        }

        return
    }