Files
bulma/handoff_demo.go

76 lines
1.6 KiB
Go
Raw Permalink 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"
"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()
}