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)
	}
}
相关推荐
kite012112 小时前
Gin + Zap 日志:构建高性能、结构化的应用日志系统
golang·gin·log·zap
OxYGC14 小时前
[玩转GoLang] 5分钟整合Gin / Gorm框架入门
开发语言·golang·gin
向上的车轮16 小时前
基于go语言的云原生TodoList Demo 项目,验证云原生核心特性
开发语言·云原生·golang
360智汇云17 小时前
k8s交互桥梁:走进Client-Go
golang·kubernetes·交互
qq_1728055918 小时前
Go 装饰器模式学习文档
学习·golang·装饰器模式
秦禹辰19 小时前
宝塔面板安装MySQL数据库并通过内网穿透工具实现公网远程访问
开发语言·后端·golang
chen_ever20 小时前
golang之go modules
开发语言·后端·golang
今天头发还在吗1 天前
【Go】:mac 环境下GoFrame安装开发工具 gf-cli——gf_darwin_arm64
macos·golang·go·gf-cli
是誰萆微了承諾1 天前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
ifanatic1 天前
[每周一更]-(第159期):Go 工程师视角:容器化技术(Docker/Kubernetes)与CI/CD流程的应用场景
docker·golang·kubernetes