You have reached the world's edge, none but devils play past here
0%
golang sync.cond
Posted onEdited on Symbols count in article: 2.4kReading time ≈2 mins.
Cond implements a condition variable, a rendezvous(会和) point for goroutines waiting for or announcing(宣布,公告) the occurrence(发生) of an event.
Each Cond has an associated(关联) Locker L (often a *Mutex or *RWMutex), which must be held when changing the condition and when calling the Wait method.
// L is held while observing or changing the condition L Locker
notify notifyList checker copyChecker }
// Approximation of notifyList in runtime/sema.go. Size and alignment must // agree. type notifyList struct { wait uint32 notify uint32 lock uintptr// key field of the mutex head unsafe.Pointer tail unsafe.Pointer }
NewCond
NewCond returns a new Cond with Locker l.
1 2 3 4
// NewCond returns a new Cond with Locker l. funcNewCond(l Locker) *Cond { return &Cond{L: l} }
// Wait atomically unlocks c.L and suspends execution // of the calling goroutine. After later resuming execution, // Wait locks c.L before returning. Unlike in other systems, // Wait cannot return unless awoken by Broadcast or Signal. // // Because c.L is not locked when Wait first resumes, the caller // typically cannot assume that the condition is true when // Wait returns. Instead, the caller should Wait in a loop: // // c.L.Lock() // for !condition() { // c.Wait() // } // ... make use of condition ... // c.L.Unlock() // func(c *Cond)Wait() { c.checker.check() //检查有没有被copy t := runtime_notifyListAdd(&c.notify) c.L.Unlock() runtime_notifyListWait(&c.notify, t) c.L.Lock() }
check
1 2 3 4 5 6 7 8 9 10
// copyChecker holds back pointer to itself to detect object copying. type copyChecker uintptr
// Signal wakes one goroutine waiting on c, if there is any. // // It is allowed but not required for the caller to hold c.L // during the call. func(c *Cond)Signal() { c.checker.check() runtime_notifyListNotifyOne(&c.notify) }
Broadcast
1 2 3 4 5 6 7 8
// Broadcast wakes all goroutines waiting on c. // // It is allowed but not required for the caller to hold c.L // during the call. func(c *Cond)Broadcast() { c.checker.check() runtime_notifyListNotifyAll(&c.notify) }