Golang sync. Cond Source Code Analysis

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

The main function of cond is to acquire a lock, and the Wait () method waits for a notification to proceed with the next lock release, which controls the appropriate release of the lock, the release frequency, and the wait and notification for goroutine in the concurrency environment.

Sync for Golang 1.9. Cond, the same as the Golang 1.10. Source code location: Sync\cond.go.

Structural body

type Cond struct {noCopy noCopy  // noCopy可以嵌入到结构中,在第一次使用后不可复制,使用go vet作为检测使用// 根据需求初始化不同的锁,如*Mutex 和 *RWMutexL Lockernotify  notifyList  // 通知列表,调用Wait()方法的goroutine会被放入list中,每次唤醒,从这里取出checker copyChecker // 复制检查,检查cond实例是否被复制}

Take a look at the wait queue notifyList structure:

type notifyList struct {wait   uint32notify uint32lock   uintptrhead   unsafe.Pointertail   unsafe.Pointer}

Function

Newcond

Equivalent Cond constructor that is used for initialization Cond .

The argument is initialized for the locker instance and must be a reference or pointer when passing arguments, such as &sync. mutex{} or new (sync. Mutex), or it will report an exception: cannot use lock (type sync.Mutex) as type sync.Locker in argument to sync.NewCond .
You can think about why it must be a pointer. Know can give me a message to answer.

func NewCond(l Locker) *Cond {return &Cond{L: l}}

Wait

Wait for auto unlock C. L and Pause execution call Goroutine. After resuming execution, wait for lock C. L before returning. Unlike other systems, the wait cannot be returned unless it is awakened by a broadcast or signal.

Because C. When waiting for the first recovery, L is not locked, and the caller usually cannot assume that the condition is correct when the wait is returned. Instead, the caller should wait in the loop:

func (c *Cond) Wait() {    // 检查c是否是被复制的,如果是就panicc.checker.check()// 将当前goroutine加入等待队列t := runtime_notifyListAdd(&c.notify)// 解锁c.L.Unlock()// 等待队列中的所有的goroutine执行等待唤醒操作runtime_notifyListWait(&c.notify, t)c.L.Lock()}

Determines whether the cond is copied.

type copyChecker uintptrfunc (c *copyChecker) check() {if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&uintptr(*c) != uintptr(unsafe.Pointer(c)) {panic("sync.Cond is copied")}}

Signal

A goroutine in the wake-up waiting queue, which is generally a goroutine in any wake queue, why is there no FIFO mode selected? This is because FIFO mode is inefficient, although supported, but rarely used.

func (c *Cond) Signal() {    // 检查c是否是被复制的,如果是就panicc.checker.check()// 通知等待列表中的一个 runtime_notifyListNotifyOne(&c.notify)}

Broadcast

Wakes all goroutine in the wait queue.

func (c *Cond) Broadcast() {    // 检查c是否是被复制的,如果是就panicc.checker.check()// 唤醒等待队列中所有的goroutineruntime_notifyListNotifyAll(&c.notify)}

Instance

 package mainimport ("FMT" "Sync" "Time") var locker = new (sync. Mutex) var cond = sync. Newcond (Locker) func main () {for i: = 0; i <; i++ {go func (x int) {cond. L.lock ()//Get lock defer cond. L.unlock ()//release lock cond. Wait ()//waits for notification to block the current GOROUTINEFMT. PRINTLN (x) time. Sleep (time. Second * 1)} (i)}time. Sleep (time. Second * 1) fmt. Println ("Signal ...") cond. Signal ()//Send a notification to the goroutinetime that has acquired the lock. Sleep (time. Second * 1) cond. Signal ()///3 seconds after sending a notification to the goroutinetime that has acquired the lock. Sleep (time. Second * 3) cond. Broadcast ()///3 seconds after the broadcast to all the waiting goroutinefmt. PRINTLN ("Broadcast ...") time. Sleep (time. Second *)}  
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.