Documentation ¶
Overview ¶
Package sync implements primitives for synchronization between processes.
Index ¶
- Constants
- Variables
- func DestroyCond(name string) error
- func DestroyEvent(name string) error
- func DestroyMutex(name string) error
- func DestroyRWMutex(name string) error
- func DestroySemaMutex(name string) error
- func DestroySemaphore(name string) error
- func DestroySpinMutex(name string) error
- type Cond
- type Event
- type IPCLocker
- type RWMutex
- type SemaMutex
- type Semaphore
- type SpinMutex
- type TimedIPCLocker
- type TimedSemaphore
Examples ¶
Constants ¶
const ( // CSemMaxVal is the maximum semaphore value, // which is guaranteed to be supported on all platforms. CSemMaxVal = 32767 )
Variables ¶
var ( // MaxCondWaiters is the maximum length of the waiting queue for this type of a cond. // This limit is actual for waitlist-based condvars, currently on windows and darwin. // If this limit is exceeded, Wait/WaitTimeout will panic with ErrTooManyWaiters. MaxCondWaiters = 128 // ErrTooManyWaiters is an error, that indicates, that the waiting queue is full. ErrTooManyWaiters = errors.New("waiters limit has been reached") )
Functions ¶
func DestroyCond ¶ added in v0.3.0
DestroyCond permanently removes condvar with the given name.
func DestroyEvent ¶ added in v0.4.0
DestroyEvent permanently destroys an event with the given name.
func DestroyMutex ¶
DestroyMutex permanently removes mutex with the given name.
func DestroyRWMutex ¶ added in v0.4.0
DestroyRWMutex permanently removes mutex with the given name.
func DestroySemaMutex ¶ added in v0.4.0
DestroySemaMutex permanently removes mutex with the given name.
func DestroySemaphore ¶ added in v0.4.0
DestroySemaphore removes the semaphore permanently.
func DestroySpinMutex ¶
DestroySpinMutex removes a mutex object with the given name
Types ¶
type Cond ¶ added in v0.3.0
type Cond cond
Cond is a named interprocess condition variable.
Example ¶
DestroyMutex("mut") mut, err := NewMutex("mut", os.O_CREATE|os.O_EXCL, 0666) if err != nil { panic("new") } defer mut.Close() DestroyCond("cond") cond, err := NewCond("cond", os.O_CREATE|os.O_EXCL, 0666, mut) if err != nil { panic("new") } defer cond.Close() var sharedValue int go func() { mut.Lock() defer mut.Unlock() sharedValue = 1 cond.Signal() }() mut.Lock() defer mut.Unlock() if sharedValue == 0 { cond.Wait() if sharedValue == 0 { panic("bad value") } }
Output:
func NewCond ¶ added in v0.3.0
NewCond returns new interprocess condvar.
name - unique condvar name. flag - a combination of open flags from 'os' package. perm - object's permission bits. l - a locker, associated with the shared resource.
type Event ¶ added in v0.4.0
type Event event
Event is a synchronization primitive used for notification. If it is signaled by a call to Set(), it'll stay in this state, unless someone calls Wait(). After it the event is reset into non-signaled state.
Example ¶
event, err := NewEvent("event", os.O_CREATE|os.O_EXCL, 0666, false) if err != nil { return } go func() { event.Set() }() if event.WaitTimeout(time.Millisecond * 250) { // event has been set } else { // timeout elapsed } event.Destroy()
Output:
func NewEvent ¶ added in v0.4.0
NewEvent creates a new interprocess event. It uses the default implementation on the current platform.
name - object name. flag - flag is a combination of open flags from 'os' package. perm - object's permission bits.
func (*Event) Set ¶ added in v0.4.0
func (e *Event) Set()
Set sets the specified event object to the signaled state.
type IPCLocker ¶
IPCLocker is a minimal interface, which must be satisfied by any synchronization primitive on any platform.
Example ¶
DestroyMutex("mut") mut, err := NewMutex("mut", os.O_CREATE|os.O_EXCL, 0666) if err != nil { panic("new") } defer mut.Close() var sharedValue uint64 var wg sync.WaitGroup wg.Add(8) for i := 0; i < 8; i++ { go func() { defer wg.Done() mut, err := NewMutex("mut", 0, 0) if err != nil { panic("new") } defer mut.Close() for i := 0; i < 1000000; i++ { mut.Lock() sharedValue++ mut.Unlock() } }() } wg.Wait() if sharedValue != 8*1000000 { panic("invalid value ") }
Output:
type RWMutex ¶ added in v0.4.0
type RWMutex struct {
// contains filtered or unexported fields
}
RWMutex is a mutex, that can be held by any number of readers or one writer.
Example ¶
const ( writers = 4 readers = 10 ) DestroyRWMutex("rw") m, err := NewRWMutex("rw", os.O_CREATE|os.O_EXCL, 0666) if err != nil { panic(err) } // we create a shared array of consistently increasing ints for reading and wriring. sharedData := make([]int, 128) for i := range sharedData { sharedData[i] = i } var wg sync.WaitGroup wg.Add(writers + readers) // writers will update the data. for i := 0; i < writers; i++ { go func() { defer wg.Done() start := rand.Intn(1024) m.Lock() for i := range sharedData { sharedData[i] = i + start } m.Unlock() }() } // readers will check the data. for i := 0; i < readers; i++ { go func() { defer wg.Done() m.RLock() for i := 1; i < len(sharedData); i++ { if sharedData[i] != sharedData[i-1]+1 { panic("bad data") } } m.RUnlock() }() } wg.Wait() fmt.Println("done")
Output: done
func NewRWMutex ¶ added in v0.4.0
NewRWMutex returns new RWMutex
name - object name. flag - flag is a combination of open flags from 'os' package. perm - object's permission bits.
func (*RWMutex) Lock ¶ added in v0.4.0
func (rw *RWMutex) Lock()
Lock locks the mutex exclusively. It panics on an error.
func (*RWMutex) RLock ¶ added in v0.4.0
func (rw *RWMutex) RLock()
RLock locks the mutex for reading. It panics on an error.
func (*RWMutex) RLocker ¶ added in v0.4.0
RLocker returns a Locker interface that implements the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
type SemaMutex ¶ added in v0.4.0
type SemaMutex struct {
// contains filtered or unexported fields
}
SemaMutex is a semaphore-based mutex for unix.
func NewSemaMutex ¶ added in v0.4.0
NewSemaMutex creates a new semaphore-based mutex.
name - object name. flag - flag is a combination of open flags from 'os' package. perm - object's permission bits.
func (*SemaMutex) Lock ¶ added in v0.4.0
func (m *SemaMutex) Lock()
Lock locks the mutex. It panics on an error.
type Semaphore ¶ added in v0.4.0
type Semaphore interface { // Signal increments the value of semaphore variable by 1, waking waiting process (if any). Signal(count int) // Wait decrements the value of semaphore variable by -1, and blocks if the value becomes negative. Wait() io.Closer }
Semaphore is a synchronization object with a resource counter, which can be used to control access to a common resource.
Example ¶
// create new semaphore with initial count set to 3. DestroySemaphore("sema") sema, err := NewSemaphore("sema", os.O_CREATE|os.O_EXCL, 0666, 3) if err != nil { panic(err) } defer sema.Close() // in the following cycle we consume three units of the resource and won't block. for i := 0; i < 3; i++ { sema.Wait() fmt.Println("got one resource unit") } // the following two goroutines won't continue until we call Signal(). var wg sync.WaitGroup wg.Add(2) for i := 0; i < 2; i++ { go func() { defer wg.Done() // open existing semaphore sema, err := NewSemaphore("sema", 0, 0666, 0) if err != nil { panic(err) } defer sema.Close() sema.Wait() fmt.Println("got one resource unit after waiting") }() } // wake up goroutines fmt.Println("waking up...") sema.Signal(2) wg.Wait() fmt.Println("done")
Output: got one resource unit got one resource unit got one resource unit waking up... got one resource unit after waiting got one resource unit after waiting done
func NewSemaphore ¶ added in v0.4.0
NewSemaphore creates new semaphore with the given name.
name - object name. flag - flag is a combination of open flags from 'os' package. perm - object's permission bits. initial - this value will be added to the semaphore's value, if it was created.
type SpinMutex ¶
type SpinMutex struct {
// contains filtered or unexported fields
}
SpinMutex is a synchronization object which performs busy wait loop.
func NewSpinMutex ¶
NewSpinMutex creates a new spin mutex.
name - object name. flag - flag is a combination of open flags from 'os' package. perm - object's permission bits.
func (*SpinMutex) Close ¶
Close indicates, that the object is no longer in use, and that the underlying resources can be freed.
func (*SpinMutex) Lock ¶
func (spin *SpinMutex) Lock()
Lock locks the mutex waiting in a busy loop if needed.
func (*SpinMutex) LockTimeout ¶ added in v0.3.0
LockTimeout locks the mutex waiting in a busy loop for not longer, than timeout.
type TimedIPCLocker ¶
type TimedIPCLocker interface { IPCLocker // LockTimeout tries to lock the locker, waiting for not more, than timeout LockTimeout(timeout time.Duration) bool }
TimedIPCLocker is a locker, whose lock operation can be limited with duration.
Example ¶
DestroyMutex("mut") mut, err := NewMutex("mut", os.O_CREATE|os.O_EXCL, 0666) if err != nil { panic("new") } defer mut.Close() tmut, ok := mut.(TimedIPCLocker) if !ok { panic("not a timed locker") } var sharedValue int rand.Seed(time.Now().Unix()) go func() { mut, err := NewMutex("mut", 0, 0) if err != nil { panic("new") } defer mut.Close() mut.Lock() // change value after [0..500] ms delay. time.Sleep(time.Duration(rand.Int()%6) * time.Millisecond * 100) sharedValue = 1 mut.Unlock() }() // give another goroutine some time to lock the mutex. time.Sleep(10 * time.Millisecond) if tmut.LockTimeout(250 * time.Millisecond) { if sharedValue != 1 { panic("bad value") } tmut.Unlock() } else { } // timeout elapsed
Output:
type TimedSemaphore ¶ added in v0.4.0
type TimedSemaphore interface { Semaphore // WaitTimeout decrements the value of semaphore variable by 1. // If the value becomes negative, it waites for not longer than timeout. WaitTimeout(timeout time.Duration) bool }
TimedSemaphore is a semaphore, that supports timed waiting. Currently supported on all platforms, except darwin.