105 lines
3.5 KiB
Go
105 lines
3.5 KiB
Go
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("所有核心场景验证完成")
|
||
}
|