mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 01:48:11 +00:00
- docs/zh/架构迁移评估.md: C ABI→子进程+共享内存完整迁移论证(1621行) - docs/zh/experiments/: 18项可复跑可行性实验(架构评估的所有数字来源) - plan.md §11: 11.1~11.9 插件架构缺陷修复清单(唯一权威编号) - main 保持干净,本批次为 update 特性分支的整改起点
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
//go:build ignore
|
||
package main
|
||
|
||
import (
|
||
"bufio"
|
||
"encoding/binary"
|
||
"encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
|
||
"golang.org/x/sys/unix"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== 实验 8:跨进程并发扇出改写同一 StageContext(最高风险点 3.4)===")
|
||
|
||
mfd, _ := unix.MemfdCreate("stagectx", 0)
|
||
unix.Ftruncate(mfd, 65536)
|
||
shmFile := os.NewFile(uintptr(mfd), "shm")
|
||
data, _ := unix.Mmap(mfd, 0, 65536, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
|
||
|
||
// 初始 final_text = "" @1024, arena 游标 = 1024
|
||
binary.LittleEndian.PutUint32(data[0:4], 1024)
|
||
binary.LittleEndian.PutUint32(data[4:8], 0)
|
||
binary.LittleEndian.PutUint32(data[8:12], 1024)
|
||
|
||
tags := []string{"A", "B", "C", "D", "E"} // 5 个并发插件
|
||
var mu sync.Mutex // 内核侧锁仲裁
|
||
var wg sync.WaitGroup
|
||
var rpcCount int64
|
||
var cntMu sync.Mutex
|
||
|
||
t0 := time.Now()
|
||
for _, tag := range tags {
|
||
cmd := exec.Command("go", "run", "exp8_worker.go", tag)
|
||
cmd.ExtraFiles = []*os.File{shmFile}
|
||
sin, _ := cmd.StdinPipe()
|
||
sout, _ := cmd.StdoutPipe()
|
||
cmd.Stderr = os.Stderr
|
||
cmd.Start()
|
||
wg.Add(1)
|
||
go func() {
|
||
defer wg.Done()
|
||
dec := json.NewDecoder(bufio.NewReader(sout))
|
||
w := bufio.NewWriter(sin)
|
||
enc := json.NewEncoder(w)
|
||
held := false
|
||
for {
|
||
var q map[string]string
|
||
if err := dec.Decode(&q); err != nil { break }
|
||
switch q["method"] {
|
||
case "stage.lock": mu.Lock(); held = true
|
||
case "stage.unlock": if held { mu.Unlock(); held = false }
|
||
}
|
||
cntMu.Lock(); rpcCount++; cntMu.Unlock()
|
||
enc.Encode(map[string]bool{"ok": true}); w.Flush()
|
||
}
|
||
if held { mu.Unlock() }
|
||
cmd.Wait()
|
||
}()
|
||
}
|
||
wg.Wait()
|
||
dur := time.Since(t0)
|
||
|
||
off := binary.LittleEndian.Uint32(data[0:4])
|
||
ln := binary.LittleEndian.Uint32(data[4:8])
|
||
final := string(data[off : off+ln])
|
||
|
||
fmt.Printf("\n--- 结果 ---\n")
|
||
fmt.Printf("最终 final_text 长度 = %d\n", len(final))
|
||
counts := map[string]int{}
|
||
for _, t := range tags { counts[t] = strings.Count(final, t) }
|
||
fmt.Printf("各插件写入次数: %v\n", counts)
|
||
total := 0
|
||
for _, c := range counts { total += c }
|
||
fmt.Printf("总字符 = %d, 长度 = %d → %s\n", total, len(final),
|
||
map[bool]string{true:"一致 ✅ 无丢失/无撕裂", false:"不一致 ❌"}[total == len(final)])
|
||
fmt.Printf("RPC 锁操作 = %d 次, 总耗时 %v\n", rpcCount, dur)
|
||
fmt.Printf("\n注:写入次数少于 5×300 是 arena 64KB 上限所致(append-only 未压实),符合设计\n")
|
||
}
|