runtime

runtime

包含 go 里面原生支持的类型,如 chan

  • chan

详细介绍:https://draveness.me/golang/concurrency/golang-channel.html

// 跳过 buf 直接发送给 receiver
if sg := c.recvq.dequeue(); sg != nil {
		// Found a waiting receiver. We pass the value we want to send
		// directly to the receiver, bypassing the channel buffer (if any).
		send(c, sg, ep, func() { unlock(&c.lock) }, 3)
		return true
}

buf => 循环数组

  • defer

  • mutex 饥饿模式

竞争模式转化为队列排队模式,防止部分 goroutine 一直争抢不到锁(或者时间较长)

自旋(Spinnig)其实是在多线程同步的过程中使用的一种机制,自旋的优点是避免了 Goroutine 的切换。

  • golang gc
  • WaitGroup:Add 和 Wait 互相等待和唤醒,Add 之后为 0 唤醒 Wait G;count 不为 0 休眠 Wait G

等待 main 程序退出除了用 WaitGroup 还可以使用 Channel 监听命令行退出信号

type WaitGroup struct {
    noCopy noCopy  // noCopy 的主要作用就是保证 WaitGroup 不会被开发者通过再赋值的方式进行拷贝
                   // checker copyChecker 运行期间的 copy 检查,Cond 有该属性,发生了则 panic
    state1 [3]uint32
}


wg := &sync.WaitGroup{}   
count := 10
wg.Add(count)
for i:=0; i<10; i++ {
  go func() {
    defer wg.Done()   // exec 10 times
  }
}
wg.Wait()  // Wait 10 times Done


ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
<-ch
  • Cond: Broadcast 广播唤醒所有 G / Signal 唤醒队列最前的 G (goready/gopark 唤醒/阻塞)

  • ErrGroup:收集多个 G 执行的错误

  • Semaphore:信号量,用来控制资源的使用

  • SingleFlight: 控制相同时间对下游的重复请求(redis 热点缓存失效)


更多精彩请扫码关注如下公众号。