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)
	}
}
相关推荐
程序员爱钓鱼4 小时前
Go语言项目工程化 — 常见开发工具与 CI/CD 支持
开发语言·后端·golang·gin
GO兔1 天前
开篇:GORM入门——Go语言的ORM王者
开发语言·后端·golang·go
代码讲故事1 天前
多种方法实现golang中实现对http的响应内容生成图片
开发语言·chrome·http·golang·图片·快照·截图
weixin_437398211 天前
转Go学习笔记
linux·服务器·开发语言·后端·架构·golang
Code季风1 天前
深入比较 Gin 与 Beego:Go Web 框架的两大选择
开发语言·golang·go·gin·beego
Code季风1 天前
Gin 中间件详解与实践
学习·中间件·golang·go·gin
九班长1 天前
Golang服务端处理Unity 3D游戏地图与碰撞的详细实现
3d·unity·golang
cui_win2 天前
【基础】Golang语言开发环境搭建(Linux主机)
linux·golang·运维开发
叹一曲当时只道是寻常2 天前
Softhub软件下载站实战开发(十):实现图片视频上传下载接口
golang·go·音视频
qq_168278952 天前
Protobuf在游戏开发中的应用:TypeScript + Golang 实践
服务器·golang·游戏引擎