mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
- docs/zh/架构迁移评估.md: C ABI→子进程+共享内存完整迁移论证(1621行) - docs/zh/experiments/: 18项可复跑可行性实验(架构评估的所有数字来源) - plan.md §11: 11.1~11.9 插件架构缺陷修复清单(唯一权威编号) - main 保持干净,本批次为 update 特性分支的整改起点
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
//go:build ignore
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"runtime"
|
||
"sync"
|
||
"sync/atomic"
|
||
"time"
|
||
|
||
"golang.org/x/sys/unix"
|
||
)
|
||
|
||
func threads() int { e, _ := os.ReadDir("/proc/self/task"); return len(e) }
|
||
|
||
func main() {
|
||
fmt.Println("=== 实验 1:eventfd 是否走 Go netpoller(只 park goroutine 不占 OS 线程)===")
|
||
base := threads()
|
||
fmt.Printf("基线线程数: %d (GOMAXPROCS=%d)\n\n", base, runtime.GOMAXPROCS(0))
|
||
|
||
const N = 200 // 模拟 200 个订阅者等待
|
||
var wg sync.WaitGroup
|
||
var woke int64
|
||
files := make([]*os.File, N)
|
||
|
||
for i := 0; i < N; i++ {
|
||
efd, err := unix.Eventfd(0, unix.EFD_NONBLOCK|unix.EFD_CLOEXEC)
|
||
if err != nil { fmt.Println("eventfd 失败:", err); return }
|
||
f := os.NewFile(uintptr(efd), fmt.Sprintf("evt%d", i))
|
||
files[i] = f
|
||
wg.Add(1)
|
||
go func(f *os.File) {
|
||
defer wg.Done()
|
||
buf := make([]byte, 8)
|
||
// 阻塞读:若走 netpoller 只 park goroutine
|
||
if _, err := f.Read(buf); err == nil {
|
||
atomic.AddInt64(&woke, 1)
|
||
}
|
||
}(f)
|
||
}
|
||
|
||
time.Sleep(500 * time.Millisecond) // 让所有 goroutine 进入等待
|
||
waiting := threads()
|
||
fmt.Printf("%d 个 goroutine 阻塞在 eventfd.Read 后:\n", N)
|
||
fmt.Printf(" 线程数 = %d (增长 %d)\n", waiting, waiting-base)
|
||
if waiting-base < 20 {
|
||
fmt.Println(" ✅ 走 netpoller:线程未随等待者数量增长")
|
||
} else {
|
||
fmt.Printf(" ❌ 退化为阻塞 syscall:每个等待者占一个 OS 线程\n")
|
||
}
|
||
|
||
// 全部唤醒
|
||
one := []byte{1,0,0,0,0,0,0,0}
|
||
for _, f := range files { f.Write(one) }
|
||
wg.Wait()
|
||
fmt.Printf("\n唤醒数 = %d/%d 唤醒后线程数 = %d\n", woke, N, threads())
|
||
}
|