semaphore

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2022 License: MIT Imports: 1 Imported by: 0

README

Semaphore GO

A simple semaphore implementation for Golang.

A semaphore is a variable or abstract data type used to control access to a common resource by multiple threads and avoid critical section problems in a concurrent system such as a multitasking operating system. Semaphores are a type of synchronization primitive.

Usage

The Semaphore type has a very simple API consisting of three methods: Acquire, TryAcquire, and Release. Acquire and TryAcquire are used to acquire the semaphore. Acquire is blocking but accepts a context so the operation can be cancelled or timeout, and TryAcquire is non-blocking. In contrast Release is used to release the Semaphore after it's been acquired.

Calls to release should always be paired with successful acquisitions of the Semaphore to release the Semaphore. Calling Release when there wasn't a successful acquire can/will lead to a deadlock.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/jkratz55/semaphore-go"
)

func main()  {
	sem := semaphore.New(5) // create a semaphore with max concurrency of 5

	for i:=0; i < 20; i++ {
		go func(id int) {
			_ = sem.Acquire(context.Background())
			defer sem.Release()

			fmt.Printf("ID %d\n", id)
			time.Sleep(time.Second * 5)
		}(i)
	}

	if sem.TryAcquire() {
		fmt.Printf("I tried and I made it!\n")
		sem.Release() // Release should only be called if acquiring the Semaphore succeeded
	} else {
		fmt.Printf("Ahhhh snap! I didn't make it\n")
	}

	time.Sleep(time.Second * 30) // don't do this at home, this is just lazy way to ensure the program finishes
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Semaphore

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

Semaphore provides functionality to limit and control concurrent access to a resource. The concurrency limit is controlled by the limited provided when a Semaphore is created using the New function.

Setting the limit to one will result in the Semaphore behaving like a mutex, but if you need the behavior of a mutex you should use sync.Mutex instead.

The zero-value is not usable and a Semaphore should be created using the New function.

func New

func New(limit int) *Semaphore

New creates a new Semaphore with the given concurrency limit.

If a limit value of < 1 is provided this function will panic.

func (*Semaphore) Acquire

func (s *Semaphore) Acquire(ctx context.Context) error

Acquire acquires the semaphore blocking until the semaphore/resource is available or the context is done. On success a nil error value is returned. If the context is done before the semaphore is acquired ctx.Err() is returned and the semaphore is left unchanged.

If ctx is already done Acquire might still succeed without blocking.

func (*Semaphore) Release

func (s *Semaphore) Release()

Release releases a single acquirement of the Semaphore.

Note: Improper use of this API can lead to a deadlock! Release should always be paired with either Acquire or TryAcquire, and only if they successfully acquired the Semaphore.

func (*Semaphore) TryAcquire

func (s *Semaphore) TryAcquire() bool

TryAcquire acquires the semaphore without blocking. On success returns true. On failure returns false and leaves the semaphore unchanged.

Jump to

Keyboard shortcuts

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