You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Go协程的网页爬虫Worker池:通道关闭问题咨询

这个问题在Go并发爬虫开发里太常见了,我给你梳理个最实用的解决方案,核心就是用sync.WaitGroup来同步任务和Worker的状态,再配合一个单独的协程来安全关闭通道。

核心思路:用双WaitGroup同步任务与Worker

我们需要两个sync.WaitGroup来分别跟踪待处理的链接任务和Worker的生命周期,这样能确保所有链接都处理完毕后,再关闭通道让Worker有序退出。

具体实现步骤

  1. 初始化同步工具
    • taskWg:统计所有需要处理的链接,每新增一个待爬链接就计数+1,处理完成后计数-1。
    • workerWg:跟踪所有Worker的运行状态,启动Worker时计数+1,Worker退出时计数-1。
  2. 启动Worker池
    每个Worker会循环从links通道读取链接,直到通道关闭。处理每个链接后,调用taskWg.Done()标记任务完成。
  3. 单独协程等待任务完成
    当taskWg.Wait()返回时,说明所有链接都处理完毕,此时关闭links通道,Worker会因为通道关闭自动退出循环。
  4. 等待所有Worker退出
    最后调用workerWg.Wait(),确保所有Worker都完全结束后再进行后续操作。

完整代码示例

package main

import (
	"fmt"
	"sync"
)

// 模拟你已经实现的Parse函数,输入链接返回页面中的新链接
func Parse(link string) []string {
	// 替换成你的实际解析逻辑
	fmt.Printf("正在解析链接: %s\n", link)
	// 这里模拟返回2个新链接
	return []string{fmt.Sprintf("%s/subpage1", link), fmt.Sprintf("%s/subpage2", link)}
}

func main() {
	// 初始化你定义的链接通道
	links := make(chan string)
	var taskWg sync.WaitGroup
	var workerWg sync.WaitGroup

	// 启动Worker池,比如启动3个Worker
	workerCount := 3
	for i := 0; i < workerCount; i++ {
		workerWg.Add(1)
		go func(workerID int) {
			defer workerWg.Done() // Worker退出时标记完成
			// 循环读取通道,直到通道关闭
			for link := range links {
				// 调用Parse解析当前链接,获取新链接
				newLinks := Parse(link)
				// 将新链接加入任务队列,注意先更新计数再发送
				for _, newLink := range newLinks {
					taskWg.Add(1)
					links <- newLink
				}
				// 当前链接处理完成,减少任务计数
				taskWg.Done()
			}
			fmt.Printf("Worker %d 已完成所有任务,退出\n", workerID)
		}(i + 1)
	}

	// 加入初始爬取任务
	initialLink := "https://example.com"
	taskWg.Add(1)
	links <- initialLink

	// 启动协程:等待所有任务完成后关闭通道
	go func() {
		taskWg.Wait()
		close(links)
		fmt.Println("所有链接任务处理完毕,已关闭链接通道")
	}()

	// 等待所有Worker完全退出
	workerWg.Wait()
	fmt.Println("所有Worker均已完成任务")
}

关键细节提示

  • 任务计数的时机:一定要先调用taskWg.Add(1)再往通道发送链接,避免taskWg.Wait()提前触发导致通道被过早关闭。
  • 链接去重:上面的示例没有做去重处理,实际爬虫里你需要加一个全局的已爬集合(比如sync.Map),避免重复处理同一个链接导致任务无限循环。
  • 可选扩展:如果需要支持中途取消任务(比如超时、用户中断),可以结合context.Context来增强生命周期管理,核心逻辑还是配合WaitGroup关闭通道。

内容的提问来源于stack exchange,提问作者pp492

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:55:40