Go Barrier栅栏

1. 简介

实现与pythonthreading.Barrier库类似的功能,多线程同时等待达到指定数量一起放行。

有待改进地方

  1. wait方法没有支持context控制。

2. 代码

go 复制代码
import (
	"context"
	"golang.org/x/sync/semaphore"
	"sync/atomic"
)

type Barrier struct {
	count  int64 // 记录当前多少
	amount int64 // 记录多少放行
	entry  *semaphore.Weighted
	exit   *semaphore.Weighted
}

func NewBarrier(n int64) *Barrier {
	b := &Barrier{
		count:  0,
		amount: n,
		entry:  semaphore.NewWeighted(n),
		exit:   semaphore.NewWeighted(n),
	}
	_ = b.exit.Acquire(context.Background(), n)
	return b
}

func (b *Barrier) Wait() {
	ctx := context.Background()

	// 限制进入数量
	_ = b.entry.Acquire(context.Background(), 1)

	// 如果是最后一个人,放行前面所有包括自己。
	if atomic.AddInt64(&b.count, 1) == b.amount {
		defer func() {
			b.count = 0
			b.entry.Release(b.amount)
		}()

		// 放行所有
		b.exit.Release(b.amount)
	}

	// 等待放行
	_ = b.exit.Acquire(ctx, 1)
}

测试

go 复制代码
func TestBarrier(t *testing.T) {
	b := NewBarrier(2)
	for i := 1; i <= 10; i++ {
		go func(id int) {
			b.Wait()
			t.Log("waited", id)
		}(i)
		time.Sleep(time.Second)
	}
}
相关推荐
weixin_462446238 小时前
用 Go 快速搭建一个 Coze (扣子)API 流式回复模拟接口(Mock Server)
开发语言·golang·状态模式
李迟9 小时前
Golang实践录:接口文档字段转结构体定义
开发语言·golang
资深web全栈开发12 小时前
Casbin 权限管理深度解析:优势与最佳实践
golang·casbin·权限设计·go库介绍
古城小栈13 小时前
Go + 边缘计算:工业质检 AI 模型部署实践指南
人工智能·golang·边缘计算
ChineHe15 小时前
Gin框架基础篇001_路由与路由组详解
后端·golang·gin
laozhoy115 小时前
深入理解Go语言errors.As方法:灵活的错误类型识别
开发语言·后端·golang
周杰伦_Jay15 小时前
【Go 语言】核心特性、基础语法及面试题
开发语言·后端·golang
ezreal_pan17 小时前
基于券类型路由的渐进式重构:函数式选项模式与管道模式的完美结合
设计模式·重构·golang·选项函数
顾安r18 小时前
12.17 脚本工具 自动化全局跳转
linux·前端·css·golang·html
Henry_Wu00119 小时前
go与c# 及nats和rabbitmq交互
golang·c#·rabbitmq·grpc·nats