关闭陈的僵局

alb*_*ttx 0 concurrency deadlock go

我想了解为什么这种情况会出现僵局以及为什么它不在另一种情况下.

如果我关闭goroutine内部的通道,它工作正常,但如果我关闭它后WaitGroup.Wait()会导致死锁.

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "sync"
)

var (
    wg    = sync.WaitGroup{}
    links = make(chan string)
)

func rec_readdir(depth int, path string) {
    files, _ := ioutil.ReadDir(path)
    for _, f := range files {
        if symlink, err := os.Readlink(path + "/" + f.Name()); err == nil {
            links <- path + "/" + symlink
        }
        rec_readdir(depth+1, path+"/"+f.Name())
    }
    if depth == 0 {
        wg.Done()
        // close(links) // if close here ok
    }
}

func main() {
    wg.Add(1)
    go rec_readdir(0, ".")

    for slink := range links {
        fmt.Println(slink)
    }
    wg.Wait()
    close(links) // if close here deadlock
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/Ntl_zsV5nwO

Fli*_*mzy 6

for slink := range links将继续循环直到通道关闭.所以你显然不能那个循环之后关闭.当你这样做时,你会发现僵局,正如你所观察到的那样.