Documentation ¶
Overview ¶
Package lock provides various locking utilities.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type OneTime ¶
type OneTime struct {
// contains filtered or unexported fields
}
OneTime is an object that can be locked exactly once.
The zero value is ready to use. A OneTime must not be copied after creation.
The use-case for this object is an alternative to the sync.Once object. sync.Once has two important downsides. First any call to .Do() does not return before the action has been performed. Second it requires a closure to be passed, resulting in additional code complexity. OneTime works around both of these by providing a single Lock() function that returns a boolean.
type whatever struct { lock OneTime } func (w *whatever) DoSomethingOnlyOnce() { if !w.lock.Lock() { // if the action has been started elsewhere, return immediatly. return } // ... action to perform ... }
Example ¶
// create a new onetime onetime := &OneTime{} var someWork uint64 var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() // if we can't lock, don't do any more work if !onetime.Lock() { return } atomic.AddUint64(&someWork, 1) }() } wg.Wait() fmt.Println(someWork)
Output: 1
type WorkGroup ¶
type WorkGroup struct {
// contains filtered or unexported fields
}
WorkGroup is a combination of an sync.Mutex and sync.WaitGroup.
It provides both a sync.Locker and a Add() and Done() methods. When locking the locker, all calls to Add() will block until it is unlocked.
The zero value is ready to use.
Example ¶
wg := &WorkGroup{} // perform some work wg.Add(1) go func() { defer wg.Done() fmt.Println("... first set of work ...") }() // lock the workgroup wg.Lock() // schedule some work (which won't happen until Unlock() has been called. workSched := make(chan struct{}) // closed once the work below has started go func() { wg.Add(1) close(workSched) // work has been scheduled! defer wg.Done() fmt.Println("... second set of work ...") }() wg.Wait() fmt.Println("first set of work done") wg.Unlock() <-workSched // wait until the work has been scheduled! wg.Wait() fmt.Println("second set of work done")
Output: ... first set of work ... first set of work done ... second set of work ... second set of work done
func (*WorkGroup) Add ¶
Add blocks until all calls to Lock() have been undone and then adds n to the underlying Waitgroup.