advsync provides small, keyed synchronization primitives for Go. It offers
mutexes, read/write mutexes, and semaphores backed by either a regular map or
xsync.Map.
go get github.com/vitalick/advsyncpackage main
import "github.com/vitalick/advsync"
func main() {
semaphore := advsync.NewSemaphore(2)
semaphore.Acquire()
defer func() { _ = semaphore.Release() }()
// Work with at most two concurrent callers.
}NamedMutexandNamedMutexSMmanage an independent mutex for every key.NamedRWMutexandNamedRWMutexSMprovide a keyed read/write mutex.Semaphoreusessync.Cond;SemaphoreChanuses a buffered channel.NamedSemaphore,NamedSemaphoreSM,NamedSemaphoreChan, andNamedSemaphoreChanSMprovide keyed semaphore variants.
Use the same key to acquire and release a named primitive. As with Go's standard synchronization types, a lock must be released by code that holds it.
Run the benchmark suite with:
go test -run '^$' -bench . -benchmemThe following uncontended results were measured on Windows 11, AMD Ryzen 9
9950X3D, Go 1.26.5, windows/amd64.
| Benchmark | ns/op | B/op | allocs/op |
|---|---|---|---|
NamedMutex |
28.69 | 0 | 0 |
NamedMutexSM |
31.59 | 16 | 2 |
NamedRWMutex |
36.91 | 0 | 0 |
NamedRWMutexSM |
42.27 | 48 | 2 |
Semaphore |
17.67 | 0 | 0 |
SemaphoreChan |
24.09 | 0 | 0 |
Results are a local baseline only. They vary by CPU, operating system, Go version, workload, and contention level.
Run the test suite with:
go test ./...Format and lint locally with:
golangci-lint fmt
golangci-lint runGitHub Actions runs tests and golangci-lint on every push and pull request.
This project is distributed under the GPL-2.0 license.