为了账号安全,请及时绑定邮箱和手机立即绑定

简单程序死锁,无法识别原因

简单程序死锁,无法识别原因

Go
GCT1015 2022-08-24 10:25:45
我在以下代码中遇到死锁错误,但我无法确定原因。代码的目标是以递归方式获取给定文件夹中所有文件的 sha256 哈希。(最终目标是根据哈希删除重复的文件,作为一个学习项目)为此,它会发送一个 goroutine,为每个文件生成另一个 goroutine 以获取哈希值。哈希存储在通道中,并在简单循环中在代码末尾读取。根据打印,检查所有文件,并检查wg。“添加”和“完成”似乎在正确的位置。法典:package mainimport (    "crypto/sha256"    "fmt"    "io"    "io/fs"    "log"    "os"    "path/filepath"    "sync"    "time")func get_fsha256sum(filepath string) string {    f, err := os.Open(filepath)    if err != nil {        log.Fatal(err)    }    defer f.Close()    return get_sha256sum(f)}func get_sha256sum(r io.Reader) string {    h := sha256.New()    if _, err := io.Copy(h, r); err != nil {        log.Fatal(err)    }    return fmt.Sprintf("%x", h.Sum(nil))}func main() {    start := time.Now()    ch := make(chan string, 10000)    var wg sync.WaitGroup    var get_fsha256sum_wrap = func(filepath string) {        start := time.Now()        ch <- get_fsha256sum(filepath)        fmt.Printf("%f-%s\n", filepath, time.Since(start))        wg.Done()    }    var walk_func = func(filepath string, info fs.DirEntry, err error) error {        wg.Add(1)        if err != nil {            return err        }        if info.IsDir() {            return nil        }        go get_fsha256sum_wrap(filepath)        return nil    }    var over_wrap = func(root string) {        filepath.WalkDir(root, walk_func)        wg.Wait()        close(ch)    }    go over_wrap("/run/media/user/Red/pictures_master/2021/01")    for v := range ch {        fmt.Println(v)    }    fmt.Printf("%s", time.Since(start))}错误信息:fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]:main.main()    /home/user/go_phockup/main.go:66 +0x273goroutine 18 [semacquire]:sync.runtime_Semacquire(0xc0000b8018)    /usr/local/go/src/runtime/sema.go:56 +0x45sync.(*WaitGroup).Wait(0xc0000b8010)    /usr/local/go/src/sync/waitgroup.go:130 +0x65main.main.func3(0x4e3d3f, 0x2b)    /home/go_phockup/main.go:62 +0x5ecreated by main.main    /home/user/go_phockup/main.go:65 +0x1bdexit status 2任何想法是什么问题?
查看完整描述

1 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

您的候补组正在等待比您创建的更多的 goroutine。walk_func添加到 中,但可能会在不创建新的 goroutine 的情况下返回。替换为:wg


var walk_func = func(filepath string, info fs.DirEntry, err error) error{

        if err != nil {

            return err

        }

        if info.IsDir() {

            return nil

        }

        

        wg.Add(1)

        go get_fsha256sum_wrap(filepath)

        return nil


        }


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 78 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信