Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go并发编程--循环栅栏CyclicBarrier #32

Open
kevinyan815 opened this issue Dec 15, 2020 · 0 comments
Open

Go并发编程--循环栅栏CyclicBarrier #32

kevinyan815 opened this issue Dec 15, 2020 · 0 comments

Comments

@kevinyan815
Copy link
Owner

kevinyan815 commented Dec 15, 2020

这个并发原语是极客时间专栏《Go并发编程实战课》摘录的笔记,补充了点自己的内容

CyclicBarrier也是一种并发同步原语,他允许一组goroutine彼此等待,到达一个共同的执行点(execution point)这个执行点也叫做栅栏(barrier)。同时因为它可以被重复使用,所以叫循环栅栏。具体的机制是,大家都在栅栏前等待,等全部都到齐了,就升起栅栏放行(开始执行)。

CyclicBarrierWaitGroup的功能有点类似。不过,CyclicBarrier更适合用在"固定数量的goroutine等待同一个执行点"的场景中,而且CyclicBarrier也能循环使用。WaitGroup 更适合用在"一个 goroutine 等待一组 goroutine 到达同一个执行点"的场景中,或者是不需要重用的场景中。

循环栅栏CyclicBarrier 是一个开发者借鉴Java CyclicBarrier的功能开发出来的,使用前需要先执行下面的安装命令

go get -u "github.com/marusama/cyclicbarrier"

CyclicBarrier 有两个初始化方法:

func New(parties int) CyclicBarrier
func NewWithAction(parties int, barrierAction func() error) CyclicBarrier

New 方法,它只需要一个参数,来指定循环栅栏参与者的数量;第二个方法是 NewWithAction,额外提供一个函数,可以在每一次到达执行点的时候执行一次。具体的时间点是在最后一个参与者到达之后,但是其它的参与者还未被放行之前。我们可以利用它,做放行之前的一些共享状态的更新等操作。

CyclicBarrier的接口定义如下:

type CyclicBarrier interface {
    // 等待所有的参与者到达,如果被ctx.Done()中断,会返回ErrBrokenBarrier
    Await(ctx context.Context) error

    // 重置循环栅栏到初始化状态。如果当前有等待者,那么它们会返回ErrBrokenBarrier
    Reset()

    // 返回当前等待者的数量
    GetNumberWaiting() int

    // 参与者的数量
    GetParties() int

    // 循环栅栏是否处于中断状态
    IsBroken() bool
}

循环栅栏的使用也很简单。循环栅栏的参与者只需调用 Await 等待,等所有的参与者都到达后,再放行执行下一步。当执行下一步的时候,循环栅栏的状态又恢复到初始的状态了,可以迎接下一轮同样多的参与者。

应用示例

并发趣题--H2O制造工厂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant