描述
Go 中的阻塞分析有助于您分析程序在等待下列阻塞操作上的花费时间:
select
chan send
chan receive
semacquire (
Mutex.Lock
,RWMutex.RLock
,RWMutex.Lock
,WaitGroup.Wait
)notifyListWait (
Cond.Wait
) 只有当 Go 通过将 goroutine 置于等待状态来暂停执行时,时间才会被跟踪。例如Mutex.Lock()
,如果锁可以立即或通过少量自旋被获得,那么这样的操作将不会出现在您的分析结果中。
上面的操作是 Go 运行时使用的等待状态的子集,下面的操作将不会出现在分析文件中:
time.Sleep(但是 time.After, time.Tick 和其他封装了 channel 的操作会显示出来)
垃圾回收
系统调用(例如网络 I/O,文件 I/O 等)
运行时内部锁(例如 stopTheWorld)
cgo 阻塞调用
永远阻塞的事件(例如在 nil 通道上发送/接收)
阻止尚未完成的事件
在某些场景下, Goroutine Profiling (debug=2) 可能是阻塞分析的一个很好的文档,因为它涵盖了所有等待状态,并且可以显示尚未完成且正在进行的阻塞事件。
用法
阻塞分析器默认是被禁用的。您可以通过按下面方式通过传递 rate > 0
来启用它。
runtime.SetBlockProfileRate(rate)
参数 rate
会影响分析器的精度和开销。在文档中,rate 是这样描述的:
SetBlockProfileRate 控制 goroutine 阻塞事件在阻塞分析中的比例。分析器旨在对每个阻塞事件耗时以纳秒级进行平均采样。如果想要囊括全部的阻塞事件,可将 rate 置为 1。完全关闭则置为 0。
就个人而言,我很难理解第二句。我更喜欢这样描述 rate
(又名 blockprofilerate
):
rate <= 0
完全禁用分析器(默认设置)rate == 1
跟踪每个阻塞事件,不论事件的duration
是多少。