在 Go 中,你可以使用 time
包来跟踪 Goroutine 的运行时间,并结合 runtime
包的功能来输出堆栈信息。下面是一个示例,展示了如何检测运行超过 20 分钟的 Goroutine 并输出它们的堆栈信息。
以下是实现该功能的步骤:
- 使用一个定时器定期检查所有 Goroutine 的运行时间。
- 对于每个正在运行的 Goroutine,如果其运行时间超过 20 分钟,则调用
runtime.Stack
来获取堆栈信息并输出。
以下是示例代码:
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
var wg sync.WaitGroup
func longRunningTask(id int) {
defer wg.Done()
startTime := time.Now()
// 模拟长时间运行任务,这里用 Sleep 来模拟
for {
if time.Since(startTime) > 20*time.Minute {
fmt.Printf("Goroutine %d has been running for more than 20 minutes\n", id)
printStack()
break
}
time.Sleep(1 * time.Second) // 每秒检查一次
}
}
func printStack() {
buf := make([]byte, 1<<16) // 分配一个大的缓冲区以存储堆栈信息
n := runtime.Stack(buf, true)
fmt.Printf("Stack trace:\n%s\n", buf[:n])
}
func main() {
const numTasks = 5
wg.Add(numTasks)
for i := 0; i < numTasks; i++ {
go longRunningTask(i)
}
wg.Wait()
fmt.Println("All tasks completed.")
}
代码说明:
longRunningTask:这是一个模拟长时间运行任务的函数。在循环中,我们检查自开始以来是否已经超过了 20 分钟。如果超过,就调用
printStack()
函数打印当前 Goroutine 的堆栈信息。printStack:这个函数使用
runtime.Stack
获取当前程序所有 Goroutine 的堆栈信息,并打印出来。主函数 (
main
) 中启动了多个 Goroutines,并等待它们完成。
请注意,为了让这个例子有效地检测到运行超过 20 分钟的情况,你需要调整睡眠逻辑或手动控制持续时间(如引入更长时间的阻塞操作)。此外,实际测试可能需要较长时间才能观察到效果,因此可根据需要调整持续条件。
内容由零声教学AI助手提供,问题来源于学员提问