typora/daliy_note/8月归档/8.22/golang-runtime.md

182 lines
5.2 KiB
Markdown
Raw Permalink Normal View History

2024-12-11 21:48:55 -05:00
`runtime.SetBlockProfileRate` 是 Go 语言中的一个函数,用于控制阻塞操作的采样和分析。阻塞操作包括通道操作、锁的获取和等待等,这些操作可能会影响程序的性能和并发性。
## 用途
`runtime.SetBlockProfileRate` 的主要用途是开启和控制阻塞操作的采样以便于对程序的性能进行分析和优化。通过设置采样率可以捕获阻塞操作的样本并生成阻塞分析报告block profile。这些报告可以帮助你识别和诊断程序中的性能瓶颈。
## 函数签名
```
func SetBlockProfileRate(rate int)
```
- `rate`: 设置采样的阻塞事件数。当 `rate` 为正数时,每发生 `rate` 次阻塞事件,会采样一次。当 `rate` 为零时,禁用阻塞分析。
## 示例
以下是一个简单的示例,展示了如何使用 `runtime.SetBlockProfileRate` 进行阻塞分析:
```
package main
import (
"log"
"runtime"
"runtime/pprof"
"os"
"time"
)
func main() {
// 设置阻塞分析的采样率,这里设置为 1 表示每次阻塞都会采样
runtime.SetBlockProfileRate(1)
// 创建一个通道用于测试阻塞操作
ch := make(chan bool)
// 启动一个 goroutine 并阻塞在接收操作上
go func() {
<-ch
}()
// 等待一段时间以产生一些阻塞事件
time.Sleep(2 * time.Second)
// 停止阻塞分析
runtime.SetBlockProfileRate(0)
// 创建一个文件保存阻塞分析报告
f, err := os.Create("block_profile.out")
if err != nil {
log.Fatal("could not create block profile: ", err)
}
defer f.Close()
// 写入阻塞分析报告
if err := pprof.Lookup("block").WriteTo(f, 0); err != nil {
log.Fatal("could not write block profile: ", err)
}
log.Println("Block profile saved to block_profile.out")
}
```
### 运行示例
1. 运行上述代码。
2. 生成的阻塞分析报告会保存在当前目录下的 `block_profile.out` 文件中。
3. 使用 `go tool pprof` 工具查看分析报告:
```
go tool pprof block_profile.out
```
`pprof` 交互模式下,你可以使用命令如 `top`、`list` 等来查看阻塞事件的详细信息。
## 总结
`runtime.SetBlockProfileRate` 是一个强大的工具,能够帮助开发者分析和优化 Go 程序中的阻塞操作。通过调整采样率和生成阻塞分析报告,你可以更好地理解程序的性能瓶颈,并做出相应的优化。
---
`runtime.SetMutexProfileFraction` 是 Go 语言中的一个函数用于控制互斥锁mutex竞争事件的采样和分析。互斥锁竞争发生在多个 Goroutine 争用同一个锁的情况下,这可能会影响程序的并发性能。
## 用途
`runtime.SetMutexProfileFraction` 的主要用途是开启和控制互斥锁竞争事件的采样以便于对程序的锁竞争情况进行分析和优化。通过设置采样率可以捕获锁竞争事件的样本并生成互斥锁竞争分析报告mutex profile。这些报告可以帮助你识别和诊断程序中的锁竞争瓶颈。
## 函数签名
```
func SetMutexProfileFraction(rate int) int
```
- `rate`: 设置采样的互斥锁竞争事件数。当 `rate` 为正数时,每发生 `rate` 次竞争事件,会采样一次。当 `rate` 为零时,禁用互斥锁竞争分析。
- 返回值:返回先前设置的采样率。
## 示例
以下是一个简单的示例,展示了如何使用 `runtime.SetMutexProfileFraction` 进行互斥锁竞争分析:
```
package main
import (
"log"
"os"
"runtime"
"runtime/pprof"
"sync"
"time"
)
func main() {
// 设置互斥锁竞争分析的采样率,这里设置为 1 表示每次竞争都会采样
prevRate := runtime.SetMutexProfileFraction(1)
log.Printf("Previous mutex profile rate: %d\n", prevRate)
// 创建一个互斥锁用于测试竞争操作
var mu sync.Mutex
// 启动多个 goroutine 并竞争获取锁
for i := 0; i < 10; i++ {
go func(i int) {
for j := 0; j < 1000; j++ {
mu.Lock()
time.Sleep(10 * time.Millisecond) // 模拟一些工作
mu.Unlock()
}
}(i)
}
// 等待一段时间以产生一些竞争事件
time.Sleep(5 * time.Second)
// 停止互斥锁竞争分析
runtime.SetMutexProfileFraction(0)
// 创建一个文件保存互斥锁竞争分析报告
f, err := os.Create("mutex_profile.out")
if err != nil {
log.Fatal("could not create mutex profile: ", err)
}
defer f.Close()
// 写入互斥锁竞争分析报告
if err := pprof.Lookup("mutex").WriteTo(f, 0); err != nil {
log.Fatal("could not write mutex profile: ", err)
}
log.Println("Mutex profile saved to mutex_profile.out")
}
```
### 运行示例
1. 运行上述代码。
2. 生成的互斥锁竞争分析报告会保存在当前目录下的 `mutex_profile.out` 文件中。
3. 使用 `go tool pprof` 工具查看分析报告:
```
go tool pprof mutex_profile.out
```
`pprof` 交互模式下,你可以使用命令如 `top`、`list` 等来查看互斥锁竞争事件的详细信息。
## 总结
`runtime.SetMutexProfileFraction` 是一个有用的工具,能够帮助开发者分析和优化 Go 程序中的互斥锁竞争情况。通过调整采样率和生成互斥锁竞争分析报告,你可以更好地理解程序的锁竞争瓶颈,并做出相应的优化。