package main import ( "fmt" "os" "runtime" "sync" "time" ) // 验证系统调用阻塞触发Hand Off func testSyscallHandoff() { runtime.GOMAXPROCS(1) // 限制P的数量为1,放大Hand Off效果 var wg sync.WaitGroup readyCh := make(chan struct{}) // 启动G1:执行阻塞式系统调用 wg.Add(1) go func() { defer wg.Done() // 创建管道用于阻塞读取 r, w, err := os.Pipe() if err != nil { fmt.Printf("创建管道失败: %v\n", err) return } defer r.Close() defer w.Close() fmt.Println("G1: 执行阻塞系统调用(sleep 2s)") close(readyCh) // 通知主goroutine G1已准备好阻塞 // 创建缓冲区 buf := make([]byte, 1) // 在后台goroutine中2秒后写入数据解除阻塞 go func() { time.Sleep(2 * time.Second) w.Write([]byte{1}) // 写入一个字节解除读取阻塞 }() // 执行阻塞读取(真正的系统调用阻塞) _, _ = r.Read(buf) fmt.Println("G1: 系统调用完成,恢复执行") }() // 等待G1准备好阻塞 <-readyCh // 短暂延迟,确保G1已进入阻塞状态 time.Sleep(50 * time.Millisecond) // 启动G2:验证Hand Off后P可调度新G wg.Add(1) go func() { defer wg.Done() fmt.Println("G2: 开始执行(验证Hand Off生效)") for i := 0; i < 5; i++ { fmt.Printf("G2: 执行中... %d\n", i) time.Sleep(300 * time.Millisecond) } fmt.Println("G2: 执行完成") }() wg.Wait() fmt.Println("所有G执行完成,验证结束") } func main() { // 先设置GOMAXPROCS,再获取 runtime.GOMAXPROCS(1) fmt.Printf("当前P的数量: %d\n", runtime.GOMAXPROCS(0)) testSyscallHandoff() }