github.com/wangyougui/gf/v2@v2.6.5/os/gproc/gproc_manager.go (about) 1 // Copyright GoFrame Author(https://goframe.org). 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/wangyougui/gf. 6 7 package gproc 8 9 import ( 10 "os" 11 12 "github.com/wangyougui/gf/v2/container/gmap" 13 "github.com/wangyougui/gf/v2/errors/gerror" 14 ) 15 16 // Manager is a process manager maintaining multiple processes. 17 type Manager struct { 18 processes *gmap.IntAnyMap // Process id to Process object mapping. 19 } 20 21 // NewManager creates and returns a new process manager. 22 func NewManager() *Manager { 23 return &Manager{ 24 processes: gmap.NewIntAnyMap(true), 25 } 26 } 27 28 // NewProcess creates and returns a Process object. 29 func (m *Manager) NewProcess(path string, args []string, environment []string) *Process { 30 p := NewProcess(path, args, environment) 31 p.Manager = m 32 return p 33 } 34 35 // GetProcess retrieves and returns a Process object. 36 // It returns nil if it does not find the process with given `pid`. 37 func (m *Manager) GetProcess(pid int) *Process { 38 if v := m.processes.Get(pid); v != nil { 39 return v.(*Process) 40 } 41 return nil 42 } 43 44 // AddProcess adds a process to current manager. 45 // It does nothing if the process with given `pid` does not exist. 46 func (m *Manager) AddProcess(pid int) { 47 if m.processes.Get(pid) == nil { 48 if process, err := os.FindProcess(pid); err == nil { 49 p := m.NewProcess("", nil, nil) 50 p.Process = process 51 m.processes.Set(pid, p) 52 } 53 } 54 } 55 56 // RemoveProcess removes a process from current manager. 57 func (m *Manager) RemoveProcess(pid int) { 58 m.processes.Remove(pid) 59 } 60 61 // Processes retrieves and returns all processes in current manager. 62 func (m *Manager) Processes() []*Process { 63 processes := make([]*Process, 0) 64 m.processes.RLockFunc(func(m map[int]interface{}) { 65 for _, v := range m { 66 processes = append(processes, v.(*Process)) 67 } 68 }) 69 return processes 70 } 71 72 // Pids retrieves and returns all process id array in current manager. 73 func (m *Manager) Pids() []int { 74 return m.processes.Keys() 75 } 76 77 // WaitAll waits until all process exit. 78 func (m *Manager) WaitAll() { 79 processes := m.Processes() 80 if len(processes) > 0 { 81 for _, p := range processes { 82 _ = p.Wait() 83 } 84 } 85 } 86 87 // KillAll kills all processes in current manager. 88 func (m *Manager) KillAll() error { 89 for _, p := range m.Processes() { 90 if err := p.Kill(); err != nil { 91 return err 92 } 93 } 94 return nil 95 } 96 97 // SignalAll sends a signal `sig` to all processes in current manager. 98 func (m *Manager) SignalAll(sig os.Signal) error { 99 for _, p := range m.Processes() { 100 if err := p.Signal(sig); err != nil { 101 err = gerror.Wrapf(err, `send signal to process failed for pid "%d" with signal "%s"`, p.Process.Pid, sig) 102 return err 103 } 104 } 105 return nil 106 } 107 108 // Send sends data bytes to all processes in current manager. 109 func (m *Manager) Send(data []byte) { 110 for _, p := range m.Processes() { 111 _ = p.Send(data) 112 } 113 } 114 115 // SendTo sneds data bytes to specified processe in current manager. 116 func (m *Manager) SendTo(pid int, data []byte) error { 117 return Send(pid, data) 118 } 119 120 // Clear removes all processes in current manager. 121 func (m *Manager) Clear() { 122 m.processes.Clear() 123 } 124 125 // Size returns the size of processes in current manager. 126 func (m *Manager) Size() int { 127 return m.processes.Size() 128 }