头图

Preface

channel specially created for synchronous communication in Go, so the use of sync.Cond is rarely seen. But it is also one of the concurrency control methods. Today we will get to know its related implementation and deepen the use of the synchronization mechanism.

sync.Cond

sync.Cond provides three methods: Wait(), Signal(), Broadcast(), their usage is as follows:

  • Wait(): Block the current goroutine and wait for it to be awakened.
  • Signal(): Arouse a blocking goroutine.
  • Broadcast(): evoke all blocked goroutines.

Through the above method description, we can simply implement a task pool function: first create goroutines in batches, and then call the Wait() method of sync.Cond to block them.

When a task arrives, a certain goroutine that was blocked just now is invoked through Signal() to perform the task.

Pool function through the task, we found that the use of sync.Cond is very simple, but we do not recommend the use of official Go sync.Cond to achieve synchronous communication between the coroutine .

Because it does not conform to the Go official "Share memory through communication" design idea, when the scene is complex, it will couple various business functions.

sync.Cond source code analysis

Let's take a look at the structure of sync.Cond, the code is under /sr/sync/cond.go:

type Cond struct {
    noCopy noCopy         // 不可复制
    L Locker            // 锁
    notify  notifyList    // 通知唤起列表
    checker copyChecker // 复制检测
}

You can see that there is a notify list on Cond, and this is what maintains the list of goroutines that need to be invoked.

When we call the Wait() method, we will maintain the current goroutine to the corresponding notifyList:

func (c *Cond) Wait() {
    c.checker.check()
    t := runtime_notifyListAdd(&c.notify) // 将当前 goroutine 添加到 notifyList 里
    c.L.Unlock()
    runtime_notifyListWait(&c.notify, t) // 阻塞等待
    c.L.Lock()
}

When other coroutines call Signal or Broadcast methods, they will invoke one or more goroutines runtime_notifyListNotifyOne or runtime_notifyListNotifyAll

Implementation of other synchronization methods

As mentioned earlier, sync.Cond is not recommended as a means of collaborative communication. If you want to achieve its unicast and broadcast effects, what should I do?

In fact, it is very simple. If we want to achieve unicast effect, we only need to monitor the channel signal through blocking.

If you want to achieve the broadcast arousal effect, you only need to use context to achieve this effect.


Interested friends can search the public account "Read New Technology" to follow more push articles.
you can, just like, leave a comment, share, thank you for your support!
Read new technology, read more new knowledge.
阅新技术


lincoln
57 声望12 粉丝

分享有深度、有启示的技术文章;