修改进程守护
This commit is contained in:
82
main.go
82
main.go
@@ -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
104
main.txt
Normal 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()
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user