首页
关于
统计
友链
更多
留言
Search
1
Golang 语言中的 chan 通道
1,122 阅读
2
【油猴插件推荐】可显示抖音直播间实际人数
943 阅读
3
ThinkPHP 关闭缓存
904 阅读
4
Python简单爬虫(XHS)
875 阅读
5
简单的Python爬虫代码演示
857 阅读
前端
Vue
Uni-app
Layui
Element-ui
后端
PHP
Goalng
Python
Linux
Docker
Mysql
Redis
算法
硬件
NAS
路由器
交换机
教程
杂谈
家庭网络
乱七八糟
智能家居
登录
Search
标签搜索
golang
goroutine
并发
chan
xiaomi
小米
智能家居
摄像机
家庭监控
油猴插件
CodeMan
累计撰写
14
篇文章
累计收到
10
条评论
首页
栏目
前端
Vue
Uni-app
Layui
Element-ui
后端
PHP
Goalng
Python
Linux
Docker
Mysql
Redis
算法
硬件
NAS
路由器
交换机
教程
杂谈
家庭网络
乱七八糟
智能家居
页面
关于
统计
友链
留言
搜索到
1
篇与
的结果
2023-02-18
Golang 并发编程:Goroutine 的坑与解决方案
Go 语言在并发编程领域,Go 语言的 Goroutine 是其最显著的特性之一。然而,在实际工作应用中,可能会遇到一些 Goroutine 使用上的坑。本文就是记录了我在工作中使用 Goroutine 使用陷阱以及如何避免它们。1. Goroutine 泄露Goroutine 泄露是指创建的 Goroutine 没有得到妥善处理,导致无法回收的情况。这可能会导致内存泄露和性能下降。例如:func main() { ch := make(chan int) go func() { ch <- doSomething() // 这里可能会阻塞 }() time.Sleep(1 * time.Second) }解决方案:使用 context 控制 Goroutine 的退出,或者使用 select 语句设置超时:func main() { ch := make(chan int) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() go func() { select { case ch <- doSomething(): case <-ctx.Done(): } }() time.Sleep(1 * time.Second) }2. 不同步的访问共享数据当多个 Goroutine 同时访问共享数据时,如果没有进行同步操作,可能会导致数据竞争和不可预测的结果。例如:var counter int func main() { wg := sync.WaitGroup{} for i := 0; i < 1000; i++ { wg.Add(1) go func() { counter++ wg.Done() }() } wg.Wait() fmt.Println(counter) }解决方案:使用 sync.Mutex 互斥锁或者 sync/atomic 原子操作进行同步:var counter int64 func main() { wg := sync.WaitGroup{} for i := 0; i < 1000; i++ { wg.Add(1) go func() { atomic.AddInt64(&counter, 1) wg.Done() }() } wg.Wait() fmt.Println(counter) }3. Goroutine 数量过多创建过多的 Goroutine 可能会导致内存耗尽和性能下降。例如,在处理大量任务时,我们不应该为每个任务创建一个 Goroutine。解决方案:使用 sync.WaitGroup 和有缓冲的 channel 限制 Goroutine 的数量:func main() { tasks := make(chan int, 100) wg := sync.WaitGroup{} // 创建 10 个工作 Goroutine for i := 0; i < 10; i++ { go func() { for task := range tasks { processTask(task) wg.Done() }() } // 添加任务到 channel for i := 0; i < 1000; i++ { tasks <- i wg.Add(1) } // 关闭任务 channel 并等待所有 Goroutine 完成 close(tasks) wg.Wait()4. 不正确的错误处理在 Goroutine 中处理错误时,需要确保错误能被正确捕获和处理。例如,以下代码中的错误无法正确传递给主 Goroutine:func main() { go func() { if err := doSomething(); err != nil { log.Fatal(err) } }() time.Sleep(1 * time.Second) }解决方案:使用 channel 将错误传递回主 Goroutine 进行处理:func main() { errCh := make(chan error) go func() { if err := doSomething(); err != nil { errCh <- err } close(errCh) }() for err := range errCh { if err != nil { log.Fatal(err) } } }总结Golang 的 Goroutine 提供了强大的并发能力,但在使用过程中需要注意一些坑,如 Goroutine 泄露、不同步访问共享数据、过多的 Goroutine 以及错误处理。通过学习这些常见的陷阱及其解决方案,我们可以更有效地利用 Goroutine 进行并发编程,提高程序的稳定性和性能。
2023年02月18日
682 阅读
0 评论
13 点赞