1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-05-04 22:17:34 +08:00

Merge pull request #762 from Lomanic/issue760

[process] Fix #760 implement IsRunning by checking process with same PID has same CreateTime as current process
This commit is contained in:
shirou 2019-09-14 12:16:28 +09:00 committed by GitHub
commit b5bcef9226
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 73 deletions

View File

@ -31,6 +31,7 @@ type Process struct {
numThreads int32 numThreads int32
memInfo *MemoryInfoStat memInfo *MemoryInfoStat
sigInfo *SignalInfoStat sigInfo *SignalInfoStat
createTime int64
lastCPUTimes *cpu.TimesStat lastCPUTimes *cpu.TimesStat
lastCPUTime time.Time lastCPUTime time.Time
@ -163,6 +164,7 @@ func NewProcess(pid int32) (*Process, error) {
if !exists { if !exists {
return p, ErrorProcessNotRunning return p, ErrorProcessNotRunning
} }
go p.CreateTime()
return p, nil return p, nil
} }
@ -222,6 +224,41 @@ func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration
return ret, nil return ret, nil
} }
// IsRunning returns whether the process is still running or not.
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
createTime, err := p.CreateTimeWithContext(ctx)
if err != nil {
return false, err
}
p2, err := NewProcess(p.Pid)
if err == ErrorProcessNotRunning {
return false, nil
}
createTime2, err := p2.CreateTimeWithContext(ctx)
if err != nil {
return false, err
}
return createTime == createTime2, nil
}
// CreateTime returns created time of the process in milliseconds since the epoch, in UTC.
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
if p.createTime != 0 {
return p.createTime, nil
}
createTime, err := p.createTimeWithContext(ctx)
p.createTime = createTime
return p.createTime, err
}
func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 { func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 {
if delta == 0 { if delta == 0 {
return 0 return 0

View File

@ -129,11 +129,8 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
} }
return r[0], err return r[0], err
} }
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
r, err := callPsWithContext(ctx, "etime", p.Pid, false) r, err := callPsWithContext(ctx, "etime", p.Pid, false)
if err != nil { if err != nil {
return 0, err return 0, err
@ -527,13 +524,6 @@ func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)
} }

View File

@ -93,11 +93,8 @@ func (p *Process) CmdlineSlice() ([]string, error) {
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return []string{}, common.ErrNotImplementedError return []string{}, common.ErrNotImplementedError
} }
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
@ -283,13 +280,7 @@ func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return []net.IOCountersStat{}, common.ErrNotImplementedError return []net.IOCountersStat{}, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)
} }

View File

@ -116,11 +116,8 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
return strParts, nil return strParts, nil
} }
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
@ -428,13 +425,6 @@ func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)
} }

View File

@ -130,12 +130,7 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
return p.fillSliceFromCmdlineWithContext(ctx) return p.fillSliceFromCmdlineWithContext(ctx)
} }
// CreateTime returns created time of the process in milliseconds since the epoch, in UTC. func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
_, _, _, createTime, _, _, _, err := p.fillFromStatWithContext(ctx) _, _, _, createTime, _, _, _, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
@ -550,16 +545,6 @@ func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]
return net.IOCountersByFile(pernic, filename) return net.IOCountersByFile(pernic, filename)
} }
// IsRunning returns whether the process is running or not.
// Not implemented yet.
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
// MemoryMaps get memory maps from /proc/(pid)/smaps // MemoryMaps get memory maps from /proc/(pid)/smaps
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)

View File

@ -114,11 +114,7 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return strings.Join(argv, " "), nil return strings.Join(argv, " "), nil
} }
func (p *Process) CreateTime() (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) { func (p *Process) Cwd() (string, error) {
@ -415,13 +411,6 @@ func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)
} }

View File

@ -539,3 +539,30 @@ func Test_Kill(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
cmd.Wait() cmd.Wait()
} }
func Test_IsRunning(t *testing.T) {
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("ping", "localhost", "-n", "2")
} else {
cmd = exec.Command("sleep", "1")
}
cmd.Start()
p, err := NewProcess(int32(cmd.Process.Pid))
assert.Nil(t, err)
running, err := p.IsRunning()
if err != nil {
t.Fatalf("IsRunning error: %v", err)
}
if !running {
t.Fatalf("process should be found running")
}
cmd.Wait()
running, err = p.IsRunning()
if err != nil {
t.Fatalf("IsRunning error: %v", err)
}
if running {
t.Fatalf("process should NOT be found running")
}
}

View File

@ -320,11 +320,7 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
return strings.Split(cmdline, " "), nil return strings.Split(cmdline, " "), nil
} }
func (p *Process) CreateTime() (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
ru, err := getRusage(p.Pid) ru, err := getRusage(p.Pid)
if err != nil { if err != nil {
return 0, fmt.Errorf("could not get CreationDate: %s", err) return 0, fmt.Errorf("could not get CreationDate: %s", err)
@ -659,14 +655,6 @@ func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped) return p.MemoryMapsWithContext(context.Background(), grouped)
} }