gpt4 book ai didi

go - 当所有 worker 都完成后关闭 channel

转载 作者:IT王子 更新时间:2023-10-29 02:09:51 25 4
gpt4 key购买 nike

我正在实现一个网络爬虫,我有一个 Parse 函数,它接受一个链接作为输入,并且应该返回页面中包含的所有链接。

我想充分利用 go routines 使其尽可能快。为此,我想创建一个 worker 池。

我设置了一个表示链接 links := make(chan string) 的字符串 channel ,并将其作为参数传递给 Parse 函数。我希望 worker 们通过一个独特的 channel 进行交流。当函数启动时,它从 links 中获取一个链接,对其进行解析并**对于在页面中找到的每个有效链接,将链接添加到 links

func Parse(links chan string) {
l := <- links
// If link already parsed, return
for url := newUrlFounds {
links <- url
}
}

但是,这里的主要问题是在找不到更多链接时进行指示。我想到的一种方法是在所有 worker 完成之前等待。但我不知道如何在 Go 中这样做。

最佳答案

正如 Tim 已经评论过的,不要在一个 worker 中使用同一个 channel 来读取和写入。这最终会死锁(即使有缓冲,因为 Murphy)。

一个简单得多的设计是简单地为每个 URL 启动一个 goroutine。缓冲 channel 可以作为一个简单的信号量来限制并发解析器的数量(因为被阻塞而什么都不做的 goroutines 通常可以忽略不计)。使用sync.WaitGroup等待所有工作完成。

package main

import (
"sync"
)

func main() {
sem := make(chan struct{}, 10) // allow ten concurrent parsers
wg := &sync.WaitGroup{}

wg.Add(1)
Parse("http://example.com", sem, wg)

wg.Wait()
// all done
}

func Parse(u string, sem chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()

sem <- struct{}{} // grab
defer func() { <-sem }() // release

// If URL already parsed, return.

var newURLs []string

// ...

for u := range newURLs {
wg.Add(1)
go Parse(u)
}
}

关于go - 当所有 worker 都完成后关闭 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50216602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com