Files
HomeAgent/docs/zh/experiments/plugin-arch/02-feasibility/exp8.go
dev 304cad0648 docs(plugin-arch): 归档插件架构迁移评估 + plan 第11节整改计划
- docs/zh/架构迁移评估.md: C ABI→子进程+共享内存完整迁移论证(1621行)
- docs/zh/experiments/: 18项可复跑可行性实验(架构评估的所有数字来源)
- plan.md §11: 11.1~11.9 插件架构缺陷修复清单(唯一权威编号)
- main 保持干净,本批次为 update 特性分支的整改起点
2026-08-31 11:45:52 +08:00

85 lines
2.4 KiB
Go
Raw 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.

//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")
}