猿问

Golang并发死锁

谁能帮我确定为什么在我正在编写的 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

}


富国沪深
浏览 134回答 2
2回答

浮云间

MoveFile正在获取 的副本wg,因此您在不同的 s上调用Wait()和。尝试将其作为指针传递。Done()WaitGroup

HUX布斯

尝试传递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    }
随时随地看视频慕课网APP

相关分类

Go
我要回答