技术文摘
Golang 函数中如何控制并发 goroutine 的数量
Golang 函数中如何控制并发 goroutine 的数量
在 Golang 开发中,利用 goroutine 进行并发编程能够显著提升程序的执行效率。然而,若不加控制地创建大量 goroutine,可能导致系统资源耗尽,程序性能下降甚至崩溃。学会在函数中控制并发 goroutine 的数量至关重要。
控制并发 goroutine 数量的常用方法之一是使用 sync.WaitGroup 和 sync.Mutex。sync.WaitGroup 用于等待一组 goroutine 完成,而 sync.Mutex 则用于同步访问共享资源。例如,假设有一个函数需要处理大量任务,我们可以限制同时运行的 goroutine 数量,避免资源过度消耗。
package main
import (
"fmt"
"sync"
)
func worker(id int, wg *sync.WaitGroup, mu *sync.Mutex, tasks chan int) {
defer wg.Done()
for task := range tasks {
mu.Lock()
fmt.Printf("Worker %d is processing task %d\n", id, task)
mu.Unlock()
}
}
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
tasks := make(chan int, 100)
maxGoroutines := 5
for i := 0; i < maxGoroutines; i++ {
wg.Add(1)
go worker(i, &wg, &mu, tasks)
}
for i := 1; i <= 20; i++ {
tasks <- i
}
close(tasks)
wg.Wait()
}
在上述代码中,我们创建了一个固定数量的 goroutine 池,每个 goroutine 从 tasks 通道中获取任务并处理。通过 sync.WaitGroup 等待所有 goroutine 完成任务,sync.Mutex 则确保在打印任务信息时的线程安全。
另一种更简洁高效的方法是使用信号量模式,通过 sync.Semaphore 来限制并发数量。sync.Semaphore 是 Go 1.19 引入的新类型,用于控制对共享资源的并发访问数量。
package main
import (
"fmt"
"golang.org/x/sync/semaphore"
"sync"
)
func worker2(id int, sem *semaphore.Weighted, wg *sync.WaitGroup, tasks chan int) {
defer wg.Done()
for task := range tasks {
if err := sem.Acquire(nil, 1); err!= nil {
fmt.Printf("Worker %d acquire semaphore failed: %v\n", id, err)
return
}
fmt.Printf("Worker %d is processing task %d\n", id, task)
sem.Release(1)
}
}
func main2() {
var wg sync.WaitGroup
tasks := make(chan int, 100)
maxGoroutines := 5
sem := semaphore.NewWeighted(int64(maxGoroutines))
for i := 0; i < maxGoroutines; i++ {
wg.Add(1)
go worker2(i, sem, &wg, tasks)
}
for i := 1; i <= 20; i++ {
tasks <- i
}
close(tasks)
wg.Wait()
}
在实际项目中,根据具体需求选择合适的方法控制并发 goroutine 数量。通过合理控制并发度,能够充分利用系统资源,提升程序的性能和稳定性。
TAGS: 并发控制 Golang并发 Golang函数 goroutine数量
- 微服务 CI/CD 实践之 GitOps 完整规划与落地
- Python 批量文件压缩处理实战教程
- 分布式配置中心(Nacos 与 Apollo)选型对比
- AR 是什么 其未来发展趋势如何
- 虚拟现实或成更具创造性的通信手段
- 谈谈中间件开发
- 原来 SOLID 原则这样理解超简单!
- C++ 基础教程(适合有 C 语言基础 二)
- 五分钟明晰 Spring Boot 自动配置原理
- 深入剖析 CSS-in-JS 一文
- IDEA 敏捷开发的实用技巧——后缀完善
- Messari:探究 Web3 的本质
- 探究阅读 Nodejs 源码的原因
- 春节时,我以责任链模式重构业务代码
- Python 知识点每日分享:一招将所有英文单词首字母大写