讲师中心 微信公众号
AI工具推荐 视频效率加速

Go并发编程为什么会阻塞_Go阻塞原因与解决思路

浅磊同学_5974

浅磊同学_5974

发布时间:2026-01-16 09:54:02

|

486人浏览过

|

来源于php中文网

原创

向无缓冲 channel 发送数据时若无接收协程,会永久阻塞并触发死锁 panic;常见原因包括未启动接收 goroutine 或接收逻辑被条件跳过。

go并发编程为什么会阻塞_go阻塞原因与解决思路

channel 操作未配对导致死锁

Go 中最典型的阻塞是向无缓冲 channel 发送数据时,没有协程在另一端接收,send 会永久阻塞当前 goroutine。运行时检测到所有 goroutine 都在等待(包括 main),就会 panic fatal error: all goroutines are asleep - deadlock。

常见于忘记启动接收协程,或接收逻辑被条件跳过:

ch := make(chan int)
ch <- 42 // 这里立刻死锁:没人收
  • 无缓冲 channel 必须「发送」和「接收」严格配对,且至少一个在运行中
  • 用 make(chan int, 1) 创建带缓冲 channel 可缓解,但缓冲区满后仍会阻塞
  • 调试时加 go func() { fmt.Println(<q>receiving...</q>); 快速验证是否漏了 receiver

select 默认分支缺失引发无限等待

当 select 中所有 channel 操作都不可达(如全满/全空),又没写 default,goroutine 就会挂起——这不是死锁,但行为上就是卡住不动。

例如从多个 channel 读取,但其中某个始终没数据、也没设超时:

select {
case v := <-ch1:
    fmt.Println(v)
case v := <-ch2:
    fmt.Println(v)
// 缺少 default 或 timeout,ch1 和 ch2 都没数据时就永远等
  • 想非阻塞尝试读写,必须加 default: 分支(哪怕只写 default: continue)
  • 想限时等待,用 time.After 或 time.NewTimer 接入 select
  • select {} 是经典空阻塞写法,常用于让 goroutine 永久休眠,但要确认这是有意为之

sync.WaitGroup 使用不当造成 main 提前退出或 hang 住

WaitGroup 本身不阻塞,但误用会导致预期外的阻塞或 panic。最常见的是:Add() 调用晚于 Go 启动,或 Done() 被漏调、多调。

  • 必须在 go 语句前调用 wg.Add(1),否则新 goroutine 可能已执行完 Done(),而 main 已调用 wg.Wait() 返回
  • Done() 被漏调 → Wait() 永远不返回;被多调 → panic panic: sync: negative WaitGroup counter
  • 不要在循环里反复 var wg sync.WaitGroup:每次重声明会丢掉之前的计数,应定义一次、复用

net/http 服务未设超时引发连接级阻塞

HTTP server 默认不设读写超时,客户端异常断连、慢请求、大文件上传未完成等情况,都会让 goroutine 卡在 conn.Read() 或 conn.Write() 上,堆积大量 idle goroutine。

  • 用 http.Server 的 ReadTimeout、WriteTimeout、IdleTimeout 显式控制
  • 不要依赖 context.WithTimeout 在 handler 内部做超时——它只能中断业务逻辑,无法终止底层 TCP 连接读写
  • 长连接场景(如 WebSocket)需额外处理 Ping/Pong 心跳,避免因网络闪断导致连接滞留

实际并发阻塞往往不是单点问题,而是 channel 设计、超时策略、资源释放三者耦合的结果。尤其要注意:Go 不会自动回收“卡住”的 goroutine,只要它还在等,就会一直占内存和栈空间。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

889

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2380

2023.10.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5219

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2665

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

3248

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2305

2025.08.29

Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

434

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

579

2025.11.17

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

60

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn