尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Go使用cyclicbarrier示例

Go使用cyclicbarrier示例
📅 发布时间:2026/6/20 19:48:45

github.com/marusama/cyclicbarrier 是一个 Go 语言库,用于实现 循环屏障(Cyclic Barrier) 的同步机制。它的主要功能是协调多个 goroutine 在某个点等待,直到所有 goroutine 都到达该点后,才能继续执行后续操作。以下是它的核心功能和用途:


1. 核心功能

  • 同步多个 goroutine:
    屏障会阻塞所有调用 Await() 的 goroutine,直到预设数量的 goroutine 都到达屏障点。
  • 循环使用:
    屏障可以重复使用(即“循环”),每次所有 goroutine 通过后,屏障会自动重置,可以再次用于下一轮同步。
  • 支持超时和取消:
    通过 context.Context 支持超时或取消操作,避免 goroutine 无限等待。

2. 主要用途

  • 任务分阶段执行:
    例如,多个任务需要分阶段执行,每个阶段完成后需要等待其他任务,才能进入下一阶段。
  • 模拟多人游戏:
    所有玩家加载完资源后,游戏才能开始(如代码示例中的场景)。
  • 并行计算:
    在并行计算中,多个计算任务需要同步中间结果后再继续。
  • 测试并发逻辑:
    用于测试多 goroutine 的同步行为。

3. 关键方法

  • New(n int):
    创建一个屏障,n 是需要等待的 goroutine 数量。
  • Await(ctx context.Context) error:
    调用此方法的 goroutine 会阻塞,直到所有 goroutine 都调用了 Await()。
    • 返回 nil:所有 goroutine 成功通过屏障。
    • 返回错误:可能是超时(context.DeadlineExceeded)或屏障被破坏(ErrBrokenBarrier)。

4. 与 sync.WaitGroup 的区别

  • sync.WaitGroup:
    用于等待一组 goroutine 完成,但无法重复使用。
  • cyclicbarrier:
    支持重复使用,且可以嵌入业务逻辑(如屏障通过后执行特定动作)。

5. 代码示例中的使用

在用户提供的代码中:

  1. 创建了一个屏障,参与者数量为玩家数(4)加裁判(1)。
  2. 每个玩家调用 Await() 等待其他玩家和裁判。
  3. 裁判调用 Await() 后,打印“游戏开始”作为屏障通过后的动作。

代码

package mainimport ("context""fmt""github.com/marusama/cyclicbarrier""math/rand""sync""time"
)func player(ctx context.Context, id int, b cyclicbarrier.CyclicBarrier, wg *sync.WaitGroup) {defer wg.Done()// 模拟加载资源loadTime := time.Duration(rand.Intn(3)+1) * time.Secondfmt.Printf("Player %d is loading resources (%v)...\n", id, loadTime)time.Sleep(loadTime)fmt.Printf("Player %d finished loading and is waiting...\n", id)err := b.Await(ctx)if err != nil {fmt.Printf("Player %d couldn't start the game: %v\n", id, err)return}fmt.Printf("==> Player %d has entered the game! <--\n", id)
}func main() {const numPlayers = 6// 我们增加一个特殊的goroutine,在所有玩家准备好后,由它来宣布游戏开始// 因此参与者总数是 玩家数 + 1b := cyclicbarrier.New(numPlayers)var wg sync.WaitGroupwg.Add(numPlayers)ctx := context.Background()// 启动玩家goroutinefor i := 1; i <= numPlayers; i++ {go player(ctx, i, b, &wg)}// 启动游戏裁判goroutinego func() {defer wg.Done()fmt.Println("Game Master: Waiting for all players to be ready...")// 裁判也加入等待err := b.Await(ctx)if err != nil {fmt.Printf("Game Master: Could not start the game: %v\n", err)return}// 当所有参与者(玩家+裁判)都到达后,裁判被唤醒,执行这个“栅栏动作”fmt.Println("Game Master: All players are ready. Game Start!")}()wg.Wait()
}

带超时的

package mainimport ("context""errors""fmt""github.com/marusama/cyclicbarrier""time"
)func main() {const numTasks = 3b := cyclicbarrier.New(numTasks)// 创建一个2秒后自动取消的contextctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel()for i := 0; i < numTasks; i++ {go func(id int) {// 模拟一个任务超时if id == 0 {fmt.Printf("Task %d will take a long time...\n", id)time.Sleep(5 * time.Second) // 这个任务耗时超过了context的超时时间} else {time.Sleep(1 * time.Second)}fmt.Printf("Task %d reached barrier.\n", id)err := b.Await(ctx)//  关键的错误处理if err != nil {// 使用 errors.Is 来正确判断错误类型if errors.Is(err, context.DeadlineExceeded) {fmt.Printf("Task %d: Waiting timed out! The barrier is broken.\n", id)} else if errors.Is(err, cyclicbarrier.ErrBrokenBarrier) {fmt.Printf("Task %d: The barrier was broken by another goroutine.\n", id)} else {fmt.Printf("Task %d: An unexpected error occurred: %v\n", id, err)}} else {fmt.Printf("Task %d passed the barrier.\n", id)}}(i)}time.Sleep(6 * time.Second) // 等待演示结束
}

相关新闻

  • 剑指offer-30、连续⼦数组的最⼤和
  • 小区物业的智慧:轻松图解JVM垃圾回收的奥秘
  • CUDA多版本安装切换(转链接自用)

最新新闻

  • GDB基础命令
  • 2026上海翡翠回收避坑指南|看懂行情价,拒绝虚高报价套路 - 奢侈品交易观察员
  • ahk2_lib架构解密:构建企业级AutoHotkey V2原生扩展生态
  • 3分钟免费汉化Axure:告别英文界面,拥抱高效中文设计体验
  • 论文AI写作网址有哪些?精选6款正规平台推荐 - 掌桥科研-AI论文写作
  • 2026武汉三新高级技工学校招生简章,23个热门专业覆盖理工、艺术、医学、教育等六个学科方向 - 资讯速览

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号