求问《GO 语言圣经》里这句话应该怎么解释?

yuantingwuji 19天前 14

下面这段代码来自《 GO 语言圣经》 8.6. 示例: 并发的 Web 爬虫

func main() {
    worklist := make(chan []string)  // lists of URLs, may have duplicates
    unseenLinks := make(chan string) // de-duplicated URLs

    // Add command-line arguments to worklist.
    go func() { worklist <- os.Args[1:] }()

    // Create 20 crawler goroutines to fetch each unseen link.
    for i := 0; i < 20; i++ {
        go func() {
            for link := range unseenLinks {
                foundLinks := crawl(link)
                go func() { worklist <- foundLinks }() //避免死锁
            }
        }()
    }

    // The main goroutine de-duplicates worklist items
    // and sends the unseen ones to the crawlers.
    seen := make(map[string]bool)
    for list := range worklist {
        for _, link := range list {
            if !seen[link] {
                seen[link] = true
                unseenLinks <- link
            }
        }
    }
}

书里面说,“crawl 函数爬到的链接在一个专有的 goroutine 中被发送到 worklist 中来避免死锁”,就是上面代码中加了中文注释那一行,为什么不把 worklist <- foundLinks 这个操作加入专有协程就有引起死锁呢?

最新回复 (10)
  • iceheart 15天前
    引用 2
    就是单一协程程服务的模式代替临界区访问的模式
  • ihipop 15天前
    引用 3
    一楼说的高大上,单纯从代码看,中文注释处这是把结果发送给 work list,但是 worklist 可能是满的,如果读取 work list 的那边读取慢或者不读取,爬取协程就被阻塞在写入 work list chan 那边了,把发送行为放到子协程就不影响爬取协程继续爬取。
  • ihipop 15天前
    引用 4
    @ihipop 然后
    main 函数末尾会把所有未爬取过的连接过滤一遍,再发给 unseenlinks,如果直接把 foundlinks 发现的链接直接给 crawl 爬取,那么这里可能存在重复的链接,爬虫就会陷入死循环了。
  • 楼主 yuantingwuji 15天前
    引用 5
    @ihipop 噢,我好像明白了,如果 worklist <- foundLinks 操作不加入专有协程,则会阻塞 unseenLinks 这个变量的读取,这样会进一步阻塞主协程 unseenLinks 的接收操作,进而阻塞主协程 worklist 的的读取,这样就形成死锁了。
  • yeqown 15天前
    引用 6
    unseenLinks 和 worklist 在阻塞情况下互相等待,就会出现死锁
  • mogg 15天前
    引用 7
    考虑 unseenLinks 和 worklist 都满了的情况,worklist <- foundLinks, unseenLinks <- link 都阻塞,这时候就死锁了
  • treblex 15天前
    引用 8
    跑个题,为啥接收命令行参数也要开个协程
  • VincentYe123 15天前
    引用 9
    @treblex 和上面的回答的原因一样
  • kkbblzq 15天前
    引用 10
    @treblex 因为是无缓冲区的 chan,原因还是和上面一样
  • hq136234303 15天前
    引用 11
    @ihipop 这样回照成携程的无限上涨
  • 游客
    12
返回