psem

package module
v0.0.0-...-9998d63 Latest Latest
Warning

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

Go to latest
Published: May 25, 2016 License: MIT Imports: 3 Imported by: 0

README

psem

-- import "github.com/avezila/psem"

Package psem is a warp for POSIX named semaphore functions in C.

http://linux.die.net/man/7/sem_overview

POSIX semaphores allow processes and threads to synchronize their actions. A semaphore is an integer whose value is never allowed to fall below zero. Two operations can be performed on semaphores: increment the semaphore value by one Post() and decrement the semaphore value by one Wait(). If the value of a semaphore is currently zero, then a Wait() operation will block until the value becomes greater than zero.

Benchmark on my laptop thinkpad w520:

BenchmarkPostWait-8 3000000 416 ns/op

BenchmarkPostWaitParallel-8 10000000 175 ns/op

Usage

const (
	// Creat - then the semaphore is created if it does not already exist.
	Creat = int(C.O_CREAT)

	// Excl - if both Creat and Excl are specified in oflag,
	// then an error is returned if a semaphore with the given name already exists.
	Excl = int(C.O_EXCL)

	// EAcces - The semaphore exists, but the caller does not have permission to open it.
	// or - Unlink(): The caller does not have permission to unlink this semaphore.
	EAcces = syscall.Errno(C.EACCES)
	// EExist - Both O_CREAT and O_EXCL were specified in oflag,
	// but a semaphore with this name already exists.
	EExist = syscall.Errno(C.EEXIST)
	// EInVal - value was greater than SEM_VALUE_MAX.
	// or - name consists of just "/", followed by no other characters.
	// or - sem is not a valid semaphore.
	// or - TimedWait(): The value of timout is less than 0, or greater than or equal to 1000 million.
	EInVal = syscall.Errno(C.EINVAL)
	// EMFile - The process already has the maximum number of files and open.
	EMFile = syscall.Errno(C.EMFILE)
	// ENameTooLong - name was too long.
	ENameTooLong = syscall.Errno(C.ENAMETOOLONG)
	// ENFile - The system limit on the total number of open files has been reached.
	ENFile = syscall.Errno(C.ENFILE)
	// ENoEnt - Open(): The Creat flag was not specified and no semaphore with this name exists;
	// or, Creat was specified, but name wasn't well formed.
	// or - Unlink(): There is no semaphore with the given name.
	ENoEnt = syscall.Errno(C.ENOENT)
	// ENoMem - Insufficient memory.
	ENoMem = syscall.Errno(C.ENOMEM)
	// EOverflow - The maximum allowable value for a semaphore would be exceeded.
	EOverflow = syscall.Errno(C.EOVERFLOW)
	// EIntr - The call was interrupted by a signal handler
	EIntr = syscall.Errno(C.EINTR)
	// EAgain - TryWait(): The operation could not be performed without blocking
	// (i.e., the semaphore currently has the value zero).
	EAgain = syscall.Errno(C.EAGAIN)
	// ETimedOut - TimedWait(): The call timed out before the semaphore could be locked.
	ETimedOut = syscall.Errno(C.ETIMEDOUT)
)
func Unlink(name string) error

Unlink - removes the named semaphore referred to by name. The semaphore name is removed immediately. The semaphore is destroyed once all other processes that have the semaphore open close it.

type Sem
type Sem struct {
}

Sem - struct for save pointer to the semaphore

func Open
func Open(name string, flag int, mode int, value uint) (*Sem, error)

Open - creates a new POSIX semaphore or opens an existing semaphore. The semaphore is identified by name. If Creat is specified, and a semaphore with the given name already exists, then mode and value are ignored. flag: Creat|Excl mode: for example 0600 value: initial value

func (*Sem) Close
func (sem *Sem) Close() error

Close - closes the named semaphore, allowing any resources that the system has allocated to the calling process for this semaphore to be freed.

func (*Sem) Get
func (sem *Sem) Get() (uint, error)

Get - return current value of the semaphore. If one or more processes or threads are blocked waiting to lock the semaphore with Wait() POSIX.1-2001 permits two possibilities for the value returned in sval: either 0 is returned; or a negative number whose absolute value is the count of the number of processes and threads currently blocked in Wait()

func (*Sem) Post
func (sem *Sem) Post() error

Post - increments (unlocks) the semaphore. If the semaphore's value consequently becomes greater than zero, then another process or thread blocked in a psem.Wait call will be woken up and proceed to lock the semaphore.

func (*Sem) TimedWait
func (sem *Sem) TimedWait(timeout time.Duration) error

TimedWait - is the same as Wait(), except that timeout specifies a limit on the amount of time that the call should block if the decrement cannot be immediately performed. If the timeout has already expired by the time of the call, and the semaphore could not be locked immediately, then TimedWait() fails with a timeout error. If the operation can be performed immediately, then TimedWait() never fails with a timeout error, regardless of the value of timeout. Furthermore, the validity of timeout is not checked in this case.

func (*Sem) TryWait
func (sem *Sem) TryWait() error

TryWait - is the same as Wait(), except that if the decrement cannot be immediately performed, then call returns an error instead of blocking.

func (*Sem) Wait
func (sem *Sem) Wait() error

Wait - decrements (locks) the semaphore. If the semaphore's value is greater than zero, then the decrement proceeds, and the function returns, immediately. If the semaphore currently has the value zero, then the call blocks until either it becomes possible to perform the decrement (i.e., the semaphore value rises above zero), or a signal handler interrupts the call.

Documentation

Overview

Package psem is a warp for POSIX named semaphore functions in C.

http://linux.die.net/man/7/sem_overview

POSIX semaphores allow processes and threads to synchronize their actions. A semaphore is an integer whose value is never allowed to fall below zero. Two operations can be performed on semaphores: increment the semaphore value by one Post() and decrement the semaphore value by one Wait(). If the value of a semaphore is currently zero, then a Wait() operation will block until the value becomes greater than zero.

Benchmark on my laptop thinkpad w520:

BenchmarkPostWait-8 3000000 416 ns/op

BenchmarkPostWaitParallel-8 10000000 175 ns/op

Example
sem, err := Open("/example", Creat|Excl, 0600, 1)
Unlink("/example")
defer sem.Close()
if err != nil {
	fmt.Println(err)
}
sem.Wait() // Lock
fmt.Println("safe print")
sem.Post() // Unlock

sem.Wait()
val, _ := sem.Get()
fmt.Println("semaphore value", val) // 0

err = sem.TryWait()
if err == EAgain {
	go func() {
		time.Sleep(time.Millisecond)
		sem.Post()
	}()
	err = sem.TimedWait(time.Millisecond * 5)
	fmt.Println("no error now:", err)
}
Output:

safe print
semaphore value 0
no error now: <nil>

Index

Examples

Constants

View Source
const (
	// Creat - then the semaphore is created if it does not already exist.
	Creat = int(C.O_CREAT)

	// Excl - if both Creat and Excl are specified in oflag,
	// then an error is returned if a semaphore with the given name already exists.
	Excl = int(C.O_EXCL)

	// EAcces - The semaphore exists, but the caller does not have permission to open it.
	// or - Unlink(): The caller does not have permission to unlink this semaphore.
	EAcces = syscall.Errno(C.EACCES)
	// EExist - Both O_CREAT and O_EXCL were specified in oflag,
	// but a semaphore with this name already exists.
	EExist = syscall.Errno(C.EEXIST)
	// EInVal - value was greater than SEM_VALUE_MAX.
	// or - name consists of just "/", followed by no other characters.
	// or - sem is not a valid semaphore.
	// or - TimedWait(): The value of timout is less than 0, or greater than or equal to 1000 million.
	EInVal = syscall.Errno(C.EINVAL)
	// EMFile - The process already has the maximum number of files and open.
	EMFile = syscall.Errno(C.EMFILE)
	// ENameTooLong - name was too long.
	ENameTooLong = syscall.Errno(C.ENAMETOOLONG)
	// ENFile - The system limit on the total number of open files has been reached.
	ENFile = syscall.Errno(C.ENFILE)
	// ENoEnt - Open(): The Creat flag was not specified and no semaphore with this name exists;
	// or, Creat was specified, but name wasn't well formed.
	// or - Unlink(): There is no semaphore with the given name.
	ENoEnt = syscall.Errno(C.ENOENT)
	// ENoMem - Insufficient memory.
	ENoMem = syscall.Errno(C.ENOMEM)
	// EOverflow - The maximum allowable value for a semaphore would be exceeded.
	EOverflow = syscall.Errno(C.EOVERFLOW)
	// EIntr - The call was interrupted by a signal handler
	EIntr = syscall.Errno(C.EINTR)
	// EAgain - TryWait(): The operation could not be performed without blocking
	// (i.e., the semaphore currently has the value zero).
	EAgain = syscall.Errno(C.EAGAIN)
	// ETimedOut - TimedWait(): The call timed out before the semaphore could be locked.
	ETimedOut = syscall.Errno(C.ETIMEDOUT)
)

Variables

This section is empty.

Functions

func Unlink(name string) error

Unlink - removes the named semaphore referred to by name. The semaphore name is removed immediately. The semaphore is destroyed once all other processes that have the semaphore open close it.

Types

type Sem

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

Sem - struct for save pointer to the semaphore

func Open

func Open(name string, flag int, mode int, value uint) (*Sem, error)

Open - creates a new POSIX semaphore or opens an existing semaphore. The semaphore is identified by name. If Creat is specified, and a semaphore with the given name already exists, then mode and value are ignored. flag: Creat|Excl mode: for example 0600 value: initial value

func (*Sem) Close

func (sem *Sem) Close() error

Close - closes the named semaphore, allowing any resources that the system has allocated to the calling process for this semaphore to be freed.

func (*Sem) Get

func (sem *Sem) Get() (uint, error)

Get - return current value of the semaphore. If one or more processes or threads are blocked waiting to lock the semaphore with Wait() POSIX.1-2001 permits two possibilities for the value returned in sval: either 0 is returned; or a negative number whose absolute value is the count of the number of processes and threads currently blocked in Wait()

func (*Sem) Post

func (sem *Sem) Post() error

Post - increments (unlocks) the semaphore. If the semaphore's value consequently becomes greater than zero, then another process or thread blocked in a psem.Wait call will be woken up and proceed to lock the semaphore.

func (*Sem) TimedWait

func (sem *Sem) TimedWait(timeout time.Duration) error

TimedWait - is the same as Wait(), except that timeout specifies a limit on the amount of time that the call should block if the decrement cannot be immediately performed. If the timeout has already expired by the time of the call, and the semaphore could not be locked immediately, then TimedWait() fails with a timeout error. If the operation can be performed immediately, then TimedWait() never fails with a timeout error, regardless of the value of timeout. Furthermore, the validity of timeout is not checked in this case.

func (*Sem) TryWait

func (sem *Sem) TryWait() error

TryWait - is the same as Wait(), except that if the decrement cannot be immediately performed, then call returns an error instead of blocking.

func (*Sem) Wait

func (sem *Sem) Wait() error

Wait - decrements (locks) the semaphore. If the semaphore's value is greater than zero, then the decrement proceeds, and the function returns, immediately. If the semaphore currently has the value zero, then the call blocks until either it becomes possible to perform the decrement (i.e., the semaphore value rises above zero), or a signal handler interrupts the call.

Jump to

Keyboard shortcuts

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