修改进程守护

This commit is contained in:
zyj
2025-07-14 00:13:15 +08:00
parent ef219bef1e
commit e159cf5b1c
2 changed files with 186 additions and 0 deletions

82
main.go
View File

@@ -1,9 +1,16 @@
package main
import (
"bufio"
"context"
"flag"
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"sync"
"syscall"
)
var (
@@ -34,4 +41,79 @@ func main() {
if *stop != "" {
fmt.Println("停止:", *stop)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
cmd := exec.CommandContext(ctx, "go", "run", "src\\index.go")
cmd.Dir = "D:\\project\\Go\\src\\go-fingerprint\\"
// if err := cmd.Start(); err != nil {
// fmt.Println("运行报错")
// }
// 创建管道捕获标准输出
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Errorf("创建标准输出管道失败: %v", err)
}
// 创建管道捕获标准错误
stderr, err := cmd.StderrPipe()
if err != nil {
fmt.Errorf("创建标准错误管道失败: %v", err)
}
// 启动命令
if err := cmd.Start(); err != nil {
fmt.Errorf("启动命令失败: %v", err)
}
// 使用 WaitGroup 等待输出处理完成
var wg sync.WaitGroup
wg.Add(2)
// 处理标准输出
go func() {
defer wg.Done()
scanAndCapture(stdout, "STDOUT")
}()
// 处理标准错误
go func() {
defer wg.Done()
scanAndCapture(stderr, "STDERR")
}()
// 等待命令执行完成
if err := cmd.Wait(); err != nil {
fmt.Errorf("命令执行失败: %v", err)
}
setupSignalHandler()
// 等待所有输出处理完成
wg.Wait()
cmd.Wait()
}
// 扫描并捕获输出
func scanAndCapture(reader io.Reader, prefix string) {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()
var outputLines []string
// 捕获输出行最多保留1000行
outputLines = append(outputLines, line)
if len(outputLines) > 1000 {
outputLines = outputLines[1:]
}
// 实时显示
fmt.Printf("[%s] %s\n", prefix, line)
}
}
func setupSignalHandler() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigChan
fmt.Println("\n接收到中断信号停止子进程...")
os.Exit(0)
}()
}

104
main.txt Normal file
View File

@@ -0,0 +1,104 @@
package main
import (
"bufio"
"context"
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"sync"
"syscall"
)
func main() {
// 1. 创建上下文用于任务控制
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 2. 设置信号处理Ctrl+C
setupSignalHandler(cancel)
// 3. 创建并配置命令
cmd := createCommand(ctx, "go", "run", "src\\index.go")
cmd.Dir = "D:\\project\\Go\\src\\go-fingerprint\\"
// 4. 获取输出管道
stdout := getOutputPipe(cmd, "stdout")
stderr := getOutputPipe(cmd, "stderr")
// 5. 启动任务
if err := cmd.Start(); err != nil {
fmt.Printf("启动失败: %v\n", err)
return
}
fmt.Printf("任务已启动 (PID: %d)\n", cmd.Process.Pid)
// 6. 启动输出处理协程
var wg sync.WaitGroup
wg.Add(2)
go processOutput(&wg, stdout, "OUT")
go processOutput(&wg, stderr, "ERR")
// 7. 等待任务完成
if err := cmd.Wait(); err != nil {
fmt.Printf("任务结束: %v\n", err)
}
// 8. 等待所有输出处理完成
wg.Wait()
fmt.Println("程序退出")
}
// 创建可执行命令
func createCommand(ctx context.Context, command string, args ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, command, args...)
cmd.Dir = "." // 设置工作目录
return cmd
}
// 获取输出管道
func getOutputPipe(cmd *exec.Cmd, stream string) io.Reader {
var pipe io.Reader
var err error
switch stream {
case "stdout":
pipe, err = cmd.StdoutPipe()
case "stderr":
pipe, err = cmd.StderrPipe()
}
if err != nil {
fmt.Printf("创建%s管道失败: %v\n", stream, err)
return nil
}
return pipe
}
// 处理任务输出
func processOutput(wg *sync.WaitGroup, reader io.Reader, prefix string) {
defer wg.Done()
if reader == nil {
return
}
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Printf("[%s] %s\n", prefix, scanner.Text())
}
}
// 设置信号处理
func setupSignalHandler(cancel context.CancelFunc) {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigChan
fmt.Println("\n收到停止信号停止任务...")
cancel()
}()
}