Files
bulma/gmp_flow_demo.go
T

105 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
var wgp sync.WaitGroup
// 辅助函数:打印Goroutine栈信息(间接判断状态)
func printGStack(msg string) {
buf := make([]byte, 2048)
n := runtime.Stack(buf, true)
fmt.Printf("\n【%s】Goroutine栈快照:\n%s\n", msg, buf[:n])
}
// demo1: 验证基础状态流转(_Gidle→_Grunnable→_Grunning→_Gdead)对应节点【A】【B】【C】
func demoBasicStateTransition() {
fmt.Println("=== demo1: 基础状态流转(对应节点【A】【B】【C】) ===")
wgp.Add(1)
go func() {
defer wgp.Done()
printGStack("G1: 运行态(_Grunning,对应节点【B】)")
time.Sleep(100 * time.Millisecond)
}()
wgp.Wait()
printGStack("G1: 退出态(_Gdead,对应节点【C】)后主线程状态")
fmt.Println("demo1 完成\n")
}
// demo2: 验证系统调用态流转(_Grunning→_Gsyscall→_Grunnable→_Gdead)对应节点【E】【I】
func demoSyscallState() {
fmt.Println("=== demo2: 系统调用态流转(对应节点【E】【I】) ===")
wgp.Add(1)
go func() {
defer wgp.Done()
fmt.Println("G2: 执行模拟系统调用(对应节点【E】)")
time.Sleep(200 * time.Millisecond) // 模拟syscall,标记为_Gsyscall
fmt.Println("G2: 系统调用完成(对应节点【I】)")
}()
time.Sleep(50 * time.Millisecond) // 等待G2进入_Gsyscall
printGStack("G2: 系统调用态(_Gsyscall,对应节点【E】)快照")
wgp.Wait()
fmt.Println("demo2 完成\n")
}
// demo3: 验证栈拷贝态流转(_Grunning→_Gcopystack→_Grunnable→_Grunning)对应节点【G】【M】
func demoCopyStackState() {
fmt.Println("=== demo3: 栈拷贝态流转(对应节点【G】【M】) ===")
wgp.Add(1)
go func() {
defer wgp.Done()
// 递归调用触发栈扩容,通过使用buf确保栈空间被真实占用
var recursiveFunc func(n int) []byte
recursiveFunc = func(n int) []byte {
if n == 0 {
printGStack("G3: 栈拷贝完成(_Gcopystack→_Grunnable,对应节点【M】)")
return make([]byte, 0)
}
buf := make([]byte, 1024*8) // 每次分配8KB,真实占用栈空间触发扩容
fmt.Printf("G3: 递归层级%d,触发栈拷贝(对应节点【G】)\n", n)
// 通过递归返回值引用buf,避免被编译器优化掉
return append(buf, recursiveFunc(n-1)...)
}
recursiveFunc(10)
}()
wgp.Wait()
fmt.Println("demo3 完成\n")
}
// demo4: 验证抢占态流转(_Grunning→_Gpreempted→_Grunnable→_Grunning)对应节点【AB】-【AE】【P】【V】
func demoPreemptedState() {
fmt.Println("=== demo4: 抢占态流转(对应节点【AB】-【AE】【P】【V】) ===")
wgp.Add(2)
// 长任务G4:运行20ms,触发抢占
go func() {
defer wgp.Done()
fmt.Println("G4: 长任务启动(_Grunning,对应节点【B】)")
start := time.Now()
for time.Since(start) < 20*time.Millisecond { /* 无函数调用,触发抢占 */
}
fmt.Println("G4: 长任务完成(_Gpreempted→_Grunnable,对应节点【P】【V】)")
}()
// 短任务G5:验证抢占后调度
go func() {
defer wgp.Done()
fmt.Println("G5: 短任务启动(_Grunnable,对应节点【A】)")
time.Sleep(50 * time.Millisecond)
fmt.Println("G5: 短任务完成(证明G4被抢占,对应节点【AE】)")
}()
wgp.Wait()
fmt.Println("demo4 完成\n")
}
func main() {
fmt.Printf("CPU核心数:%d\n初始GOMAXPROCS%d\n\n", runtime.NumCPU(), runtime.GOMAXPROCS(-1))
demoBasicStateTransition()
demoSyscallState()
demoCopyStackState()
demoPreemptedState()
fmt.Println("所有核心场景验证完成")
}