2

I am trying to count the elapsed time of a process(tracking time in a game). The following code works but keeps the CPU busy constantly. I'd imagine it's something to do with the while loop constantly polling to check if the process is still running. Could there be a more efficent way of implementing this?

def is_running(process_name):
    try:
        subprocess.check_output(['pidof', process_name])
        return True
    except subprocess.CalledProcessError:
        return False


def monitor_process(process_name):
    while True:
        if is_running(process_name):
            start_time = time.time()
            while is_running(process_name):
                pass

            return round(time.time() - start_time, 3)

        else:
            pass
Ozzy Walsh
  • 877
  • 9
  • 17
  • Where did the process get started in the first place? If your code started it, it could just leave a thread waiting for the process to terminate and skip the polling completely. – tdelaney Jun 14 '16 at 22:09
  • related: [Python subprocess with /usr/bin/time: how to capture timing info but ignore all other output?](http://stackoverflow.com/q/28520489/4279) – jfs Jun 15 '16 at 23:29

1 Answers1

3

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 our filter_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.

Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103