Provide Semaphore, SizedGroup and ErrSizedGroup

Programming language: Go
License: MIT License
Tags: Goroutines     Concurrency     Semaphore    
Latest version: v1.1.1

Syncs alternatives and similar packages

Based on the "Goroutines" category.
Alternatively, view Syncs alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Syncs or a related project?

Add another 'Goroutines' Package


Syncs - additional synchronization primitives

Build Status Go Report Card Coverage Status

Package syncs provides additional synchronization primitives.

Install and update

go get -u github.com/go-pkgz/syncs



Implements sync.Locker interface but for given capacity, thread safe. Lock increases count and Unlock - decreases. Unlock on 0 count will be blocked.

    sema := syncs.NewSemaphore(10) // make semaphore with 10 initial capacity
    for i :=0; i<10; i++ {
        sema.Lock() // all 10 locks will pass, i.w. won't lock
    sema.Lock() // this is 11 - will lock for real

    // in some other place/goroutine
    sema.Unlock() // decrease semaphore counter


Mix semaphore and WaitGroup to provide sized waiting group. The result is a wait group allowing limited number of goroutine to run in parallel.

By default, the locking happens inside of goroutine, i.e. every call will be non-blocked, but some goroutines may wait if semaphore locked. It means - technically it doesn't limit number of goroutines, but rather number of running (active) goroutines. In order to block goroutines from even starting use Preemptive option (see below).

    swg := syncs.NewSizedGroup(5) // wait group with max size=5
     for i :=0; i<10; i++ {
        swg.Go(fn func(ctx context.Context){
            doThings(ctx) // only 5 of these will run in parallel


Sized error group is a SizedGroup with error control. Works the same as errgrp.Group, i.e. returns first error. Can work as regular errgrp.Group or with early termination. Thread safe.

Supports both in-goroutine-wait via NewErrSizedGroup as well as outside of goroutine wait with Preemptive option. Another options are TermOnErr which will skip (won't start) all other goroutines if any error returned, and Context for early termination/timeouts.

Important! With Preemptive Go call can block. In case if maximum size reached the call will wait till number of running goroutines dropped under max. This way we not only limiting number of running goroutines but also number of waiting goroutines.

    ewg := syncs.NewErrSizedGroup(5, syncs.Preemptive) // error wait group with max size=5, don't try to start more if any error happened
     for i :=0; i<10; i++ {
        ewg.Go(fn func(ctx context.Context) error { // Go here could be blocked if trying to run >5 at the same time 
           err := doThings(ctx)     // only 5 of these will run in parallel
           return err
    err := ewg.Wait()