sync

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2025 License: MIT Imports: 4 Imported by: 0

README

package sync

build go reference last version sync coverage sync report card

Contents


📋 Overview

The sync package provides advanced synchronization primitives for Go, designed for correctness, performance, and ease of use in concurrent programming.

For full documentation, see https://pkg.go.dev/github.com/lif0/pkg/sync.


⚙️ Requirements

  • Go 1.19 or higher

📦 Installation

To add this package to your project, use go get:

go get github.com/lif0/pkg/sync@latest

Import the sync extension in your code:

import "github.com/lif0/pkg/sync"

✨ Features

ReentrantMutex

The ReentrantMutex type provides a reentrant mutual exclusion lock that allows the same goroutine to acquire the lock multiple times without deadlocking. It supports recursive locking, ownership tracking, and methods like Lock and Unlock.

Important details:

  • Panics on unlocking an unlocked mutex.
  • Panics on unlocking from a different goroutine than the owner.
  • Panics if recursion count goes negative.
Performance
goos: darwin
goarch: arm64
pkg: github.com/lif0/pkg/sync
cpu: Apple M2
BenchmarkMutexes/sync.Mutex-8         	                    155_743_212	         7.684 ns/op       0 B/op	       0 allocs/op
BenchmarkMutexes/sync.RWMutex-8       	                    71_501_988	        16.49 ns/op	       0 B/op	       0 allocs/op
BenchmarkMutexes/sync.ReentrantMutex-8         	            65_857_020	        17.82 ns/op	       0 B/op	       0 allocs/op

BenchmarkMutexesParallel/sync.MutexParallel-8               13_736_034          73.02 ns/op        0 B/op          0 allocs/op
BenchmarkMutexesParallel/sync.RWMutexParallel-8             14_190_777          84.19 ns/op        0 B/op          0 allocs/op
BenchmarkMutexesParallel/sync.ReentrantMutexParallel-8      35_037_007          34.84 ns/op        0 B/op          0 allocs/op
Example
Example: Basic Usage
package main

import (
    "fmt"

    "github.com/lif0/pkg/sync"
)

func main() {
    // Create a new reentrant mutex
    rm := sync.ReentrantMutex{}

    // Acquire the lock
    rm.Lock()
    fmt.Println("Acquired lock")

    // Perform critical section work
    // ...

    // Release the lock
    rm.Unlock()
    fmt.Println("Released lock")
}
Example: Recursive Locking
package main

import (
    "fmt"

    "github.com/lif0/pkg/sync"
)

func recursiveFunction(rm *sync.ReentrantMutex, depth int) {
    rm.Lock()
    defer rm.Unlock()

    fmt.Printf("Recursion depth: %d\n", depth)

    if depth > 0 {
        recursiveFunction(rm, depth-1)
    }
}

func main() {
    rm := sync.ReentrantMutex{}

    recursiveFunction(rm, 3)
}
Example: Contention Handling
package main

import (
    "fmt"
    "sync"
    "time"

    "github.com/lif0/pkg/sync"
)

func main() {
    rm := sync.NewReentrantMutex()

    rm.Lock()
    fmt.Println("Main goroutine acquired lock")

    wg := sync.WaitGroup{}
    wg.Add(1)

    go func() {
        defer wg.Done()

        fmt.Println("Worker trying to acquire lock...")
        rm.Lock()
        fmt.Println("Worker acquired lock")
        rm.Unlock()
    }()

    time.Sleep(1 * time.Second)
    rm.Unlock()
    fmt.Println("Main goroutine released lock")

    wg.Wait()
}

🗺️ Roadmap

The future direction of this package is community-driven! Ideas and contributions are highly welcome.

☹️ No idea

Contributions and feature suggestions are welcome 🤗.


📄 License

MIT

Documentation

Overview

Package sync provides synchronization utilities.

Package sync provides sync utilities.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnlockOfUnlockedMutex reports an attempt to unlock an unlocked mutex.
	ErrUnlockOfUnlockedMutex = errors.New("unlock of unlocked reentrant mutex")

	// ErrUnlockFromAnotherGoroutine reports an attempt to unlock a mutex owned by another goroutine.
	ErrUnlockFromAnotherGoroutine = errors.New("unlock from non-owner goroutine")

	// ErrUnlockWithNegativeCount Unlock with negative count.
	ErrUnlockWithNegativeCount = errors.New("unlock with negative count")
)

Functions

This section is empty.

Types

type ReentrantMutex

type ReentrantMutex struct {
	// contains filtered or unexported fields
}

A ReentrantMutex is a reentrant mutual exclusion lock. The zero value for a ReentrantMutex is an unlocked mutex.

A ReentrantMutex must not be copied after first use.

In the terminology of the Go memory model, the n'th call to ReentrantMutex.Unlock by the owning goroutine "synchronizes before" the m'th call to ReentrantMutex.Lock for any n < m, accounting for recursion levels. ReentrantMutex allows the same goroutine to acquire the lock multiple times without deadlock. It tracks the owning goroutine and recursion level; only the owning goroutine may unlock it, and the mutex is released when the recursion level reaches zero.

ReentrantMutex implements the sync.Locker interface.

func NewReentrantMutex

func NewReentrantMutex() *ReentrantMutex

NewReentrantMutex creates and initializes a new ReentrantMutex.

func (*ReentrantMutex) Lock

func (rm *ReentrantMutex) Lock()

Lock locks rm. If the lock is already held by the current goroutine, the recursion count is incremented. Otherwise, the calling goroutine blocks until the rmutex is available.

func (*ReentrantMutex) Unlock

func (rm *ReentrantMutex) Unlock()

Unlock unlocks rm. It panics if rm is not locked on entry to Unlock.

Unlock must be called by the goroutine that owns the lock. If the recursion count is greater than 1, it is decremented. If the recursion count reaches 0, the lock is released.

A locked ReentrantMutex is associated with a particular goroutine. It is not allowed for one goroutine to lock a ReentrantMutex and then arrange for another goroutine to unlock it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL