使用goroutine和channel实现多任务调度,通过WaitGroup协调生命周期。创建5个并发任务,每个任务执行完成后调用wg.Done(),主协程调用wg.Wait()等待所有任务结束,确保正确同步。

在 Golang 中实现多任务调度,核心依赖于 goroutine 和 channel 的协作机制。通过合理使用这些原语,可以高效地管理并发任务的执行、同步与通信。下面介绍几种常见的多任务调度模式及其实践方法。
使用 Goroutine 启动并发任务
每个 goroutine 是一个轻量级线程,由 Go 运行时调度。启动一个任务只需在函数调用前加上 go 关键字。
例如,同时执行多个耗时任务:
func doTask(id int) { time.Sleep(1 * time.Second) fmt.Printf("任务 %d 完成n", id)}func main() {for i := 0; i < 5; i++ {go doTask(i)}time.Sleep(2 * time.Second) // 等待所有任务完成}
注意:主协程不能过早退出,否则子协程不会执行完。生产环境中应避免使用 time.Sleep 来等待。
立即学习“go语言免费学习笔记(深入)”;
使用 WaitGroup 协调任务生命周期
sync.WaitGroup 是等待一组 goroutine 完成的标准方式。
改写上面的例子:
func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() doTask(id) }(i) } wg.Wait() // 阻塞直到所有任务完成 fmt.Println("所有任务结束")}
这里使用了闭包传参,避免了变量共享问题。每次启动 goroutine 前调用 Add(1),任务结束时调用 Done()。
通过 Channel 控制任务流与结果收集
当需要获取任务返回值或限制并发数时,channel 是更灵活的选择。
示例:从任务中获取结果并汇总:
func taskWithResult(id int, ch chan string) { time.Sleep(1 * time.Second) ch <- fmt.Sprintf("任务 %d 结果", id)}func main() {resultCh := make(chan string, 5)for i := 0; i < 5; i++ {go taskWithResult(i, resultCh)}
for i := 0; i < 5; i++ { result := <-resultCh fmt.Println(result)}close(resultCh)
}
带缓冲的 channel 可以解耦生产与消费。也可以结合 select 实现超时控制:
select {case result := <-resultCh: fmt.Println(result)case <-time.After(2 * time.Second): fmt.Println("超时")}
限制并发数量的任务池
实际场景中常需控制最大并发数,防止资源耗尽。可通过带缓冲的 channel 作为信号量来实现。
示例:最多同时运行 3 个任务:
func limitedConcurrency() { sem := make(chan struct{}, 3) // 最大并发 3 resultCh := make(chan string, 10)tasks := []int{1, 2, 3, 4, 5, 6, 7, 8}for _, id := range tasks { sem <- struct{}{} // 获取令牌 go func(taskID int) { defer func() { <-sem }() // 释放令牌 time.Sleep(1 * time.Second) resultCh <- fmt.Sprintf("处理完成: %d", taskID) }(id)}// 等待所有任务提交完毕并关闭 resultChgo func() { for i := 0; i < cap(sem); i++ { sem <- struct{}{} } close(resultCh)}()for res := range resultCh { fmt.Println(res)}
}
这种方式既能控制并发度,又能动态调度任务,适合爬虫、批量处理等场景。
基本上就这些。Golang 多任务调度的关键在于理解 goroutine 的轻量性、channel 的通信作用以及 WaitGroup 的协调能力。合理组合这些工具,就能写出清晰高效的并发程序。不复杂但容易忽略细节,比如变量捕获和资源等待。
以上就是如何用Golang实现多任务调度_Golang 多任务调度实践的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1425148.html
微信扫一扫
支付宝扫一扫