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)
	}
}
相关推荐
YGGP11 分钟前
【Golang】LeetCode 21. 合并两个有序链表
leetcode·链表·golang
看见繁华13 分钟前
GO 教程
开发语言·后端·golang
Yy_Yyyyy_zz16 分钟前
深入理解 Go 的多返回值:语法、编译原理与工程实践
开发语言·后端·golang
天远云服1 小时前
Fintech硬核架构:解析天远贷前风险报告接口在Go微服务中的解析策略
微服务·架构·golang
Grassto1 小时前
Go 在哪里找第三方包?Module 查找顺序详解
开发语言·后端·golang
nbsaas-boot11 小时前
Go 项目中如何正确升级第三方依赖(Go Modules 实战指南)
开发语言·后端·golang
HashFlag1 天前
单元测试(go)
golang·单元测试
TDengine (老段)1 天前
TDengine Go 连接器入门指南
大数据·数据库·物联网·golang·时序数据库·tdengine·涛思数据
YGGP1 天前
【Golang】LeetCode 206. 反转链表
leetcode·链表·golang
YGGP1 天前
【Golang】LeetCode 142. 环状链表 II
leetcode·链表·golang