safesight/edge/agent/internal/procctl/procctl_linux.go
tian 29d9ef5d0d refactor: 项目结构梳理 - 设备端/管理端对称布局
仓库结构:
  edge/     设备端(原根目录设备端代码整体移入)
  control/  管理端(清理后)
  docs/     文档(PRD 移入 design/)
  README.md 根导航(新增)

清理:
- control/.brainstorm 临时草稿删除
- control 根级重复文档(API表/PRD_04)并入 docs/design/
- control/plan.md -> docs/implementation/control-plan.md
- control/safesightd-linux-arm64 二进制取消版本控制(.gitignore)
- edge/transform 模型转换产物归入 models/,onnx/pt 大源文件取消跟踪(.gitignore)
- Readme.md(PRD) -> docs/design/PRD_Product_v1.2.md(避开 README 大小写冲突)

更新:
- 根 README.md 导航、docs/README.md 文档索引
- deployment.md/检查表路径加 edge/ 前缀
- .gitignore 重写(edge/control 分区规则)
2026-08-02 11:39:54 +08:00

80 lines
1.5 KiB
Go

//go:build linux
package procctl
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
"safesight-agent/internal/log"
)
func isAlive(pid int) (bool, error) {
if pid <= 0 {
return false, nil
}
p, err := os.FindProcess(pid)
if err != nil {
return false, err
}
if err := p.Signal(syscall.Signal(0)); err != nil {
return false, nil
}
return true, nil
}
func startProcess(execPath, workDir, configPath string) (int, error) {
cmd := exec.Command(execPath, "--config", configPath)
cmd.Dir = workDir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
if err := cmd.Start(); err != nil {
return 0, fmt.Errorf("start media-server: %w", err)
}
pid := cmd.Process.Pid
go func() {
err := cmd.Wait()
if err != nil {
log.Warn(fmt.Sprintf("media-server exited pid=%d err=%v", pid, err))
} else {
log.Info(fmt.Sprintf("media-server exited pid=%d", pid))
}
}()
return pid, nil
}
func stopProcess(pid int, timeout time.Duration) error {
if pid <= 0 {
return nil
}
p, err := os.FindProcess(pid)
if err != nil {
return err
}
_ = p.Signal(syscall.SIGTERM)
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
alive, _ := isAlive(pid)
if !alive {
return nil
}
time.Sleep(100 * time.Millisecond)
}
_ = p.Signal(syscall.SIGKILL)
deadline = time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
alive, _ := isAlive(pid)
if !alive {
return nil
}
time.Sleep(100 * time.Millisecond)
}
return fmt.Errorf("failed to stop pid=%d", pid)
}