semaphore

package
v0.9.0-nightly.20240207 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2024 License: Apache-2.0 Imports: 1 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lock

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

Lock represents a lock of the semaphore. After the lock is not needed any more it should be released.

type Simple

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

Simple provides a way to lock concurrent access to a resource. It only allows one caller to gain access at a time.

func (*Simple) Acquire

func (s *Simple) Acquire(t Ticket) Lock

Acquire acquires a Lock, blocking until the previous ticket is released. Ticket needs to be discarded after the call to Acquire. The Lock has to be supplied to Release after it is not needed anymore and discarded afterwards. Acquire is safe for concurrent use.

func (*Simple) Enqueue

func (s *Simple) Enqueue() Ticket

Enqueue reserves the next place in the queue and returns a Ticket used to acquire access to the Lock when it's the callers turn. The Ticket has to be supplied to Acquire and discarded afterwards. Enqueue is not safe for concurrent use.

Example

ExampleSimple demonstrates how different goroutines can be orchestrated to acquire locks in the same order as the tickets enqueued in the semaphore.

package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/conduitio/conduit/pkg/foundation/semaphore"
)

func main() {
	var sem semaphore.Simple
	var wg sync.WaitGroup

	// t2 is enqueued after t1, it can be acquired only after t1
	t1 := sem.Enqueue()
	t2 := sem.Enqueue()
	wg.Add(2)

	go func() {
		defer wg.Done()
		time.Sleep(time.Millisecond) // simulate delay in acquiring
		fmt.Println("routine 1: try acquiring the lock")
		lock := sem.Acquire(t1)
		fmt.Println("routine 1: acquired the lock")
		sem.Release(lock)
	}()
	go func() {
		defer wg.Done()
		fmt.Println("routine 2: try acquiring the lock")
		lock := sem.Acquire(t2) // acquire will block because t1 needs to be acquired first
		fmt.Println("routine 2: acquired the lock")
		sem.Release(lock)
	}()

	wg.Wait()

}
Output:

routine 2: try acquiring the lock
routine 1: try acquiring the lock
routine 1: acquired the lock
routine 2: acquired the lock

func (*Simple) Release

func (s *Simple) Release(l Lock)

Release releases the lock and allows the next ticket in line to acquire a lock. After Lock is released it should be discarded. Release is safe for concurrent use.

type Ticket

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

Ticket reserves a place in the queue and can be used to acquire access to a Lock.

Jump to

Keyboard shortcuts

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