【问题标题】:Deadlock on closing chan关闭陈的死锁
【发布时间】:2018-01-30 09:18:09
【问题描述】:

我想了解为什么这种情况会出现死锁,为什么在另一种情况下不会。

如果我关闭 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
}

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

【问题讨论】:

    标签: go concurrency deadlock


    【解决方案1】:

    for slink := range links 将继续循环,直到通道关闭。所以你显然不能在 after 那个循环之后关闭。如您所见,当您这样做时,您会遇到死锁。

    【讨论】:

    • 顺便说一句,推荐的做法是让 sending 例程无论如何都要关闭通道,在这种情况下,等待组是完全没有必要的,因为关闭通道表示 @ 987654322@ 例程已返回,将不再发送任何值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2011-05-29
    • 1970-01-01
    • 2019-11-17
    • 2020-01-18
    • 2017-06-27
    • 1970-01-01
    相关资源
    最近更新 更多