github.com/zhongdalu/gf@v1.0.0/g/os/gproc/gproc_proccess.go (about) 1 // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package gproc 8 9 import ( 10 "errors" 11 "fmt" 12 "os" 13 "os/exec" 14 "strings" 15 ) 16 17 // 子进程 18 type Process struct { 19 exec.Cmd 20 Manager *Manager // 所属进程管理器 21 PPid int // 自定义关联的父进程ID 22 } 23 24 // 创建一个进程(不执行) 25 func NewProcess(path string, args []string, environment ...[]string) *Process { 26 var env []string 27 if len(environment) > 0 { 28 env = make([]string, 0) 29 for _, v := range environment[0] { 30 env = append(env, v) 31 } 32 } else { 33 env = os.Environ() 34 } 35 env = append(env, fmt.Sprintf("%s=%s", gPROC_TEMP_DIR_ENV_KEY, os.TempDir())) 36 p := &Process{ 37 Manager: nil, 38 PPid: os.Getpid(), 39 Cmd: exec.Cmd{ 40 Args: []string{path}, 41 Path: path, 42 Stdin: os.Stdin, 43 Stdout: os.Stdout, 44 Stderr: os.Stderr, 45 Env: env, 46 ExtraFiles: make([]*os.File, 0), 47 }, 48 } 49 // 当前工作目录 50 if d, err := os.Getwd(); err == nil { 51 p.Dir = d 52 } 53 if len(args) > 0 { 54 start := 0 55 if strings.EqualFold(path, args[0]) { 56 start = 1 57 } 58 p.Args = append(p.Args, args[start:]...) 59 } 60 return p 61 } 62 63 // 开始执行(非阻塞) 64 func (p *Process) Start() (int, error) { 65 if p.Process != nil { 66 return p.Pid(), nil 67 } 68 p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_PPID_KEY, p.PPid)) 69 if err := p.Cmd.Start(); err == nil { 70 if p.Manager != nil { 71 p.Manager.processes.Set(p.Process.Pid, p) 72 } 73 return p.Process.Pid, nil 74 } else { 75 return 0, err 76 } 77 } 78 79 // 运行进程(阻塞等待执行完毕) 80 func (p *Process) Run() error { 81 if _, err := p.Start(); err == nil { 82 return p.Wait() 83 } else { 84 return err 85 } 86 } 87 88 // PID 89 func (p *Process) Pid() int { 90 if p.Process != nil { 91 return p.Process.Pid 92 } 93 return 0 94 } 95 96 // 向进程发送消息 97 func (p *Process) Send(data []byte) error { 98 if p.Process != nil { 99 return Send(p.Process.Pid, data) 100 } 101 return errors.New("invalid process") 102 } 103 104 // Release releases any resources associated with the Process p, 105 // rendering it unusable in the future. 106 // Release only needs to be called if Wait is not. 107 func (p *Process) Release() error { 108 return p.Process.Release() 109 } 110 111 // Kill causes the Process to exit immediately. 112 func (p *Process) Kill() error { 113 if err := p.Process.Kill(); err == nil { 114 if p.Manager != nil { 115 p.Manager.processes.Remove(p.Pid()) 116 } 117 return nil 118 } else { 119 return err 120 } 121 } 122 123 // Signal sends a signal to the Process. 124 // Sending Interrupt on Windows is not implemented. 125 func (p *Process) Signal(sig os.Signal) error { 126 return p.Process.Signal(sig) 127 }