mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-23 10:28:06 +00:00
- docs/zh/架构迁移评估.md: C ABI→子进程+共享内存完整迁移论证(1621行) - docs/zh/experiments/: 18项可复跑可行性实验(架构评估的所有数字来源) - plan.md §11: 11.1~11.9 插件架构缺陷修复清单(唯一权威编号) - main 保持干净,本批次为 update 特性分支的整改起点
63 lines
1.7 KiB
Go
63 lines
1.7 KiB
Go
//go:build ignore
|
||
|
||
package main
|
||
|
||
/*
|
||
#cgo LDFLAGS: -ldl
|
||
#include <dlfcn.h>
|
||
#include <stdlib.h>
|
||
typedef void (*fn)(void);
|
||
static void call(void* f){ ((fn)f)(); }
|
||
*/
|
||
import "C"
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"runtime"
|
||
"time"
|
||
"unsafe"
|
||
)
|
||
|
||
func threads() int { e,_ := os.ReadDir("/proc/self/task"); return len(e) }
|
||
|
||
func main() {
|
||
fmt.Println("=== A. cgo 模型:插件死循环,超时后能回收吗? ===")
|
||
p := C.CString("./hang.so"); h := C.dlopen(p, C.RTLD_NOW); C.free(unsafe.Pointer(p))
|
||
n := C.CString("hang_forever"); f := C.dlsym(h, n); C.free(unsafe.Pointer(n))
|
||
|
||
base := threads()
|
||
fmt.Printf(" 基线: goroutines=%d threads=%d\n", runtime.NumGoroutine(), base)
|
||
|
||
for i := 1; i <= 3; i++ {
|
||
done := make(chan string, 1)
|
||
go func() { C.call(f); done <- "ok" }() // 模拟 executeToolCallInner
|
||
select {
|
||
case <-done:
|
||
case <-time.After(600 * time.Millisecond): // 缩短的"60s 超时"
|
||
}
|
||
time.Sleep(200 * time.Millisecond)
|
||
fmt.Printf(" 第 %d 次超时后: goroutines=%d threads=%d (+%d)\n",
|
||
i, runtime.NumGoroutine(), threads(), threads()-base)
|
||
}
|
||
fmt.Println(" ❌ 每次超时永久泄漏 1 goroutine + 1 OS 线程(cgo 调用不可中断)")
|
||
|
||
fmt.Println("\n=== B. 子进程模型:同样死循环,可强杀 ===")
|
||
base2 := threads()
|
||
for i := 1; i <= 3; i++ {
|
||
cmd := exec.Command("sleep", "3600")
|
||
cmd.Start()
|
||
done := make(chan error, 1)
|
||
go func() { done <- cmd.Wait() }()
|
||
select {
|
||
case <-done:
|
||
case <-time.After(300 * time.Millisecond):
|
||
cmd.Process.Kill() // ← 可强制终止
|
||
<-done
|
||
}
|
||
fmt.Printf(" 第 %d 次超时+Kill 后: goroutines=%d threads=%d (+%d)\n",
|
||
i, runtime.NumGoroutine(), threads(), threads()-base2)
|
||
}
|
||
fmt.Println(" ✅ 零泄漏:进程被杀,OS 回收全部资源")
|
||
}
|