How to retrieve the process start time (or uptime) in python
If you are doing it from within the python program you're trying to measure, you could do something like this:
import time
# at the beginning of the script
startTime = time.time()
# ...
def getUptime():
"""
Returns the number of seconds since the program started.
"""
# do return startTime if you just want the process start time
return time.time() - startTime
Otherwise, you have no choice but to parse ps
or go into /proc/pid
. A nice bash
y way of getting the elapsed time is:
ps -eo pid,etime | grep $YOUR_PID | awk '{print $2}'
This will only print the elapsed time in the following format, so it should be quite easy to parse:
days-HH:MM:SS
(if it's been running for less than a day, it's just HH:MM:SS
)
The start time is available like this:
ps -eo pid,stime | grep $YOUR_PID | awk '{print $2}'
Unfortunately, if your process didn't start today, this will only give you the date that it started, rather than the time.
The best way of doing this is to get the elapsed time and the current time and just do a bit of math. The following is a python script that takes a PID as an argument and does the above for you, printing out the start date and time of the process:
import sys
import datetime
import time
import subprocess
# call like this: python startTime.py $PID
pid = sys.argv[1]
proc = subprocess.Popen(['ps','-eo','pid,etime'], stdout=subprocess.PIPE)
# get data from stdout
proc.wait()
results = proc.stdout.readlines()
# parse data (should only be one)
for result in results:
try:
result.strip()
if result.split()[0] == pid:
pidInfo = result.split()[1]
# stop after the first one we find
break
except IndexError:
pass # ignore it
else:
# didn't find one
print "Process PID", pid, "doesn't seem to exist!"
sys.exit(0)
pidInfo = [result.split()[1] for result in results
if result.split()[0] == pid][0]
pidInfo = pidInfo.partition("-")
if pidInfo[1] == '-':
# there is a day
days = int(pidInfo[0])
rest = pidInfo[2].split(":")
hours = int(rest[0])
minutes = int(rest[1])
seconds = int(rest[2])
else:
days = 0
rest = pidInfo[0].split(":")
if len(rest) == 3:
hours = int(rest[0])
minutes = int(rest[1])
seconds = int(rest[2])
elif len(rest) == 2:
hours = 0
minutes = int(rest[0])
seconds = int(rest[1])
else:
hours = 0
minutes = 0
seconds = int(rest[0])
# get the start time
secondsSinceStart = days*24*3600 + hours*3600 + minutes*60 + seconds
# unix time (in seconds) of start
startTime = time.time() - secondsSinceStart
# final result
print "Process started on",
print datetime.datetime.fromtimestamp(startTime).strftime("%a %b %d at %I:%M:%S %p")
Fastest way to get system uptime in Python in Linux
I don't think you can get much faster than using ctypes
to call sysinfo()
but in my tests, its slower than /proc. Those linux system programmers seem to know what they are doing!
import ctypes
import struct
def uptime3():
libc = ctypes.CDLL('libc.so.6')
buf = ctypes.create_string_buffer(4096) # generous buffer to hold
# struct sysinfo
if libc.sysinfo(buf) != 0:
print('failed')
return -1
uptime = struct.unpack_from('@l', buf.raw)[0]
return uptime
Running your two tests plus mine on my slow laptop, I got:
>>> print(timeit.timeit('ut.uptime1()', setup="import uptimecalls as ut", number=1000))
5.284219555993332
>>> print(timeit.timeit('ut.uptime2()', setup="import uptimecalls as ut", number=1000))
0.1044210599939106
>>> print(timeit.timeit('ut.uptime3()', setup="import uptimecalls as ut", number=1000))
0.11733305400412064
UPDATE
Most of the time is spent pulling in libc
and creating the buffer. If you plan to make the call repeatedly over time, then you can pull those steps out of the function and measure just the system call. In that case, this solution is the clear winner:
uptime1: 5.066633300986723
uptime2: 0.11561189399799332
uptime3: 0.007740753993857652
Efficiently measuring how long a process has been running
You ought use psutil (python system and process utilities)
to search for a running process.
Please note that the pidof
command only works on Linux based system,
Unix user either try ps
command or pgrep
command to find the pid of a running program.
This command doesn't exist on Windows.
import psutil
def filter_by_name(process_name):
for process in psutil.process_iter():
try:
if process.name() == process_name:
yield process
except psutil.NoSuchProcess:
pass
def is_running(process_name):
return any(p for p in filter_by_name(process_name))
process_name = "Mail"
if is_running(u"{0}".format(process_name)):
print(u"{0} is running.".format(process_name))
else:
print(u"Bad new, {0}'s dead!".format(process_name))
It is resource consuming to use an infinite loop
and check if a given process is running. Really inefficient!
At least, use time.sleep(sec)
to make a small pause between each iteration.
Again, psutil
can help you!
If you get a process with psutil.process_iter()
or with ourfilter_by_name()
function, you can wait for process termination.
Simply use the wait()
method with a timeout
(in sec.).
Then, when the process is finished,
you can substract the current time and the create_time()
to get process duration (in sec.).
import time
for p in filter_by_name(process_name):
p.wait(timeout=10)
print(time.time() - p.create_time())
Note: searching process by name can result to duplicates.
get system uptime with Python on a Raspberry Pi
I found another solution: https://www.raspberrypi.org/forums/viewtopic.php?t=164276
#!/usr/bin/python3
import shlex, subprocess
cmd = "uptime -p"
args = shlex.split(cmd)
p = subprocess.Popen(args, stdout=subprocess.PIPE)
output = p.communicate()
Thanks for your posted ideas.
print (output)
Related Topics
How to Plot Multiple Dataframes in Subplots
Typeerror: 'Str' Does Not Support the Buffer Interface
How Often Does Python Flush to a File
How to Crop an Image in Opencv Using Python
How to Read a (Static) File from Inside a Python Package
Check If a String Contains a Number
How Can Python Handle Systemctl Stop
Update Python on Linux 2.7 to 3.5
How to Explicitly Set Carriage Return When Doing JSON.Dump
Why Does Os.Path.Getsize() Return a Negative Number for a 10Gb File
How to Make Pip Install to Path on Linux
List All Currently Open File Handles
Why Is My Python App Stalled with 'System'/Kernel CPU Time
Scrapy: Couldn't Bind: 24: Too Many Open Files
Cannot Install Python3-Pip on Kali Linux
Virtualenv Uses Wrong Python, Even Though It Is First in $Path