Go 等待协程完成

简介: Go 等待协程完成

本文介绍了在Go语言中使用sync.WaitGroup进行goroutine同步以及通过channel实现阻塞同步的示例。作者强调了channel是官方推荐的同步方式,适合在goroutine间传递数据并确保执行顺序。

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

使用 sync.WaitGroup

为了等待 goroutine 结束,我们可以使用 sync.WaitGroup 来实现等待

package main
import (
  "fmt"
  "sync"
  "time"
)
func worker(id int, wg *sync.WaitGroup) {
  fmt.Printf("Worker %d starting\n", id)
  time.Sleep(time.Second)
  fmt.Printf("Worker %d done\n", id)
  wg.Done()  // 协程完成,等待的协程数 - 1,减到 0 的时候就继续执行 wg.Wait() 后面的代码
}
func main()  {
  var wg sync.WaitGroup
  for i := 1; i <= 5; i++ {
    wg.Add(1) // 等待的协程数 + 1
    go worker(i, &wg)
  }
  wg.Wait() // 等待所有协程完成
  fmt.Println("All done!")
}

使用 channel

package main
import (
  "fmt"
  "time"
)
func worker(id int, ch chan int) {
  fmt.Printf("Worker %d starting\n", id)
  time.Sleep(time.Second)
  ch <- id
}
func main() {
  ch := make(chan int)
  for i := 1; i <= 5; i++ {
    go worker(i, ch)
  }
  for i := 1; i <= 5; i++ {
    fmt.Printf("Worker %d done\n", <-ch)
  }
  fmt.Println("All done!")
}

chanel 的特性是从 channel 中获取数据的时候会引起阻塞,直到 channel 有数据,所以我们可以利用这个特性在 goroutine 的最后往 channel 里面放东西,

然后主协程里面从 channel 里面获取东西,只需要次数一致就可以了。

这种方式也是官方推荐的同步方式,sync 通常用于比较底层的同步


目录
相关文章
|
Cloud Native Go
你知道 GO 中的 协程可以无止境的开吗?
你知道 GO 中的 协程可以无止境的开吗?
179 0
|
2月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
Java Go 调度
GO 协程
GO 协程
141 0
|
12月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
Linux Go 调度
Go 协程为什么比进程和线程占用的系统资源低?
Go 协程为什么比进程和线程占用的系统资源低?
150 0
|
监控 Devops 测试技术
Go 语言在 DevOps 中的利器:并发与协程
【8月更文挑战第31天】
130 0
|
Go
如何在Go中进行文件操作以及如何使用协程来实现并发编程
如何在Go中进行文件操作以及如何使用协程来实现并发编程
165 2
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
567 6