本文详解 go 中因未关闭 channel 和错误使用 sync.waitgroup 导致“all goroutines are asleep - deadlock”错误的根本原因,并提供可复用的并发控制模板。
在 Go 并发编程中,all goroutines are asleep - deadlock 是一个典型且易被忽视的运行时错误。它并非语法或逻辑错误,而是程序陷入
永久阻塞状态:所有 goroutine 都在等待(如从 channel 读取、写入或等待 WaitGroup),却无人唤醒或终止,导致主 goroutine 无法继续执行而崩溃。
在你提供的代码中,问题根源有两点:
sync.WaitGroup 计数不匹配:wg.Add(len(urls)) 错误地为每个 URL 增加计数,但实际只启动了 1 个 Poller goroutine(而非 len(urls) 个)。WaitGroup 的 Add() 应与 Done() 调用次数严格对应——即每个 goroutine 生命周期 对应一次 Add(1) + Done()。当前代码中,Poller 函数内仅调用一次 wg.Done(),但 main 中却 Add(len(urls)),造成计数严重失衡,wg.Wait() 永远不会返回。
channel 未关闭导致无限阻塞:Poller 使用 for r := range in 循环持续接收数据。该循环仅在 channel 被显式关闭后才会退出。而你的写入 goroutine 在发送完所有 URL 后直接结束,既未关闭 pending channel,也未调用 wg.Done() 标记自身完成,导致 Poller 永远卡在 range 等待下一条数据,主 goroutine 则在 wg.Wait() 处死锁。
✅ 正确做法是:
以下是修复后的完整可运行示例(已适配 numPollers = 2 的并发模型):
package main
import (
"fmt"
"sync"
"time"
)
const numPollers = 2 // 启动 2 个并发 Poller
var urls = []string{
"http://www.google.com/",
"http://golang.org/",
"http://blog.golang.org/",
"http://golangtutorials.blogspot.fr",
"https://gobyexample.com/",
}
type Resource struct {
url string
}
// Poller 从 channel 拉取 *Resource 并处理(此处仅打印)
func Poller(in <-chan *Resource, wg *sync.WaitGroup) {
defer wg.Done()
for r := range in { // range 会自动在 channel 关闭后退出
fmt.Printf("Processed: %s - %s\n", r.url, time.Now().Format("15:04:05"))
}
}
func main() {
var wg sync.WaitGroup
pending := make(chan *Resource, len(urls)) // 可选:加缓冲避免发送阻塞
// 启动 numPollers 个 Poller goroutine
wg.Add(numPollers)
for i := 0; i < numPollers; i++ {
go Poller(pending, &wg)
}
// 启动 1 个发送 goroutine:写入 URL 并关闭 channel
wg.Add(1)
go func() {
defer close(pending) // ✅ 关键:发送完成后关闭 channel
defer wg.Done() // ✅ 标记发送器 goroutine 完成
for _, url := range urls {
fmt.Printf("Sending: %s\n", url)
pending <- &Resource{url: url}
}
}()
wg.Wait() // 等待所有 Poller 和发送器完成
fmt.Printf("✅ All done at %s\n", time.Now().Format("15:04:05"))
}? 关键注意事项:
掌握 channel 生命周期与 WaitGroup 计数的精确匹配,是写出健壮 Go 并发程序的基石。
# go
# golang
# ai
# google
# 并发编程
# 并发请求
# Resource
# for
# 循环
# 指针
# len
# 并发
# channel
# http
# 死锁
# 而非
# 是一个
# 完成后
# 都在
# 多个
# 才会
# 会在
# 仍是
# 很重要
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win10如何设置双wan路由器 Win10双wan路由器设置方法【指南】
Windows如何设置登录时的欢迎屏幕背景?(锁屏界面)
Win11怎么设置虚拟内存最佳大小_Windows11性能选项自定义分页文件
Mac的访达(Finder)怎么用_Mac文件管理入门教程【详解】
Windows 11登录时提示“用户配置文件服务登录失败”怎么办_Windows 11修复损坏的用户配置文件
Python数据挖掘核心算法实践_聚类分类与特征工程
Win11怎么设置任务栏图标大小_Windows11注册表TaskbarSi修改
Mac如何调整Dock栏大小和位置_Mac程序坞个性化设置
小程序里php怎么变mp4_小程序调用php生成mp4视频方法【教程】
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
Windows10电脑怎么设置虚拟内存_Win10高级系统设置性能
Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递
c++怎么设置线程优先级与cpu亲和性_c++ 多核处理器性能绑定【指南】
PHP接收参数值为空怎么办_判断和处理空参数方法说明【说明】
c# 在高并发场景下,委托和接口调用的性能对比
如何在 Go 中判断变量是否为函数类型
Windows 11怎么更改锁屏超时时间_Windows 11电源选项中设置屏幕关闭时间
php485在macos下怎么配置_php485 macOS系统配置指南【解答】
Win11麦克风没声音怎么设置_Win11麦克风权限及驱动修复【教程】
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
Win10如何优化内存使用_Win10内存优化技巧【攻略】
如何在 Go 中调用动态链接库(.so)中的函数
PHP的FastAdmin架构适合二次开发吗_特点分析【介绍】
phpstudy本地环境mysql忘记密码_重置mysqlroot密码操作流程【解答】
Linux怎么修改用户密码_Linux系统passwd命令使用与权限管理【方法】
php怎么连接数据库_MySQL数据库连接的基础代码编写【说明】
如何在Golang中指定模块版本_使用go.mod控制版本号
Python函数接口文档化_自动化说明【指导】
Win10电脑怎么设置休眠快捷键_Windows10电源按钮功能定义
Win10文件历史记录怎么用 Win10开启自动备份文件教程【防丢】
Windows服务持续崩溃怎样修复_系统服务保护机制解析
Mac如何彻底清理浏览器缓存?(Safari与Chrome)
c++怎么处理多线程死锁_c++ lock_guard与unique_lock锁管理【技巧】
C++中的constexpr和const有什么区别?(编译期常量)
Python并发安全问题_资源竞争说明【指导】
Win11开机速度慢怎么优化_Win11系统启动加速设置指南【方法】
Win11怎么更改文件夹图标_自定义Win11文件夹外观样式【详解】
Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】
Windows 11无法安全删除U盘提示设备正在使用中怎么办_Windows 11找出占用设备进程
Win11怎么设置快速访问主页_Windows11资源管理器文件夹选项
Win10如何更改电脑休眠时间_Windows10电源和睡眠选项调整
php高频调试功能有哪些_php常用调试函数与工具汇总【解答】
Win11如何设置开机问候语 Win11修改登录界面提示【技巧】
如何使用正则表达式精确匹配最多含一个换行符的 start-end 区段
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
如何用正则表达式精确匹配“start”到“end”之间最多含一个换行符的文本段
Win11怎么设置DNS服务器_Windows11修改网络适配器DNS优选
如何高效获取循环末次生成的 NumPy 数组最后一个元素(无需额外循环)
Win10怎样卸载自带Edge_Win10卸载Edge浏览器步骤【教程】
Win11怎么卸载Photos应用_Win11卸载Photos应用方法【教程】
2025-12-31
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。