代码拉取完成,页面将自动刷新
同步操作将从 gaozhichang/golang-study 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
@Time : 2022/7/14 19:49
@Author : gaozhichang
@File : signal.go
@des: 利用信号,做热启动,热加载
*/
package main
import (
"fmt"
"os"
"os/signal"
"runtime"
"runtime/pprof"
"runtime/trace"
"syscall"
"time"
)
/**
在 linux 系统,可以通过kill -signal_number pid命令向程序发送指定信号。
如上代码所示,我们硬编码指定的采样开关信号值是 31。因此,当程序运行起来后,我们在控制台输入kill -31 pid 命令,即可开启采样,再次输入kill -31 pid命令,就关闭了采样。
*/
func main() {
RegisterSignalForPrintStack(syscall.Signal(31))
//RegisterSignalForProfiling(syscall.Signal(31))
t := time.Tick(2 * time.Second)
for {
select {
case <-t:
fmt.Println("sleep 2 seconds...")
}
}
}
//依葫芦画瓢,我们再来一个打印 goroutine 堆栈信息的热开关函数,是不是很酷?
func RegisterSignalForPrintStack(sig os.Signal) {
ch := make(chan os.Signal)
signal.Notify(ch, sig)
go func() {
for range ch {
buffer := make([]byte, 1024*1024*4)
runtime.Stack(buffer, true)
fmt.Println("in RegisterSignalForPrintStack")
fmt.Println(string(buffer))
}
}()
}
/**
我们可以将基于接口触发的方式改为信号通知。
首先,构造采样功能函数(对应于 net/http/pprof 包下 init 函数中绑定的路由功能函数)。
在上述函数中,我们定义了接收信号通道ch,通过signal.Notify(ch, sig)将指定的通知信号sig与ch进行绑定。for range ch 将阻塞等待外部信号sig,随着sig信号的到来,交替进入开启或关闭采样的逻辑。
*/
func RegisterSignalForProfiling(sig os.Signal) {
ch := make(chan os.Signal)
started := false
signal.Notify(ch, sig)
go func() {
var memoryProfile, cpuProfile, traceProfile *os.File
for range ch {
if started {
pprof.StopCPUProfile()
trace.Stop()
pprof.WriteHeapProfile(memoryProfile)
memoryProfile.Close()
cpuProfile.Close()
traceProfile.Close()
started = false
} else {
cpuProfile, _ = os.Create("cpu.pprof")
memoryProfile, _ = os.Create("memory.pprof")
traceProfile, _ = os.Create("runtime.trace")
pprof.StartCPUProfile(cpuProfile)
trace.Start(traceProfile)
started = true
}
}
}()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。