Tracking CPU time of Python process and children
Question: Is there an easy way to track the CPU time of not only a Process but of any
child processes launched by it?

I tried sub-classing `multiprocessing.Process` to time an arbitrary function,
like:

    
    
    import time
    from multiprocessing import Process
    
    class TimedProcess(Process):
    
        daemon = True
    
        def __init__(self, *args, **kwargs):
            super(TimedProcess, self).__init__(*args, **kwargs)
            self.t0 = time.clock()
    
        @property
        def duration_seconds(self):
            return time.clock() - self.t0
    
    p = TimedProcess(target=my_long_running_func)
    p.start()
    while p.is_alive():
        print p.duration_seconds
        time.sleep(1)
    

However, when I tried to time functions involving Scikits-learn or other code
involving c-extensions or sub-processes, I found my `duration_sections` would
often report 0, or just a few seconds, even though the code would run for
hours. How would I fix this?


Answer: Your code almost prints the CPU time, but you're calling `time.clock()` in the
parent process instead of the child process. By using `multiprocessing.Pipe`,
you can pass the values from the child to the parent process:

    
    
    import time
    from threading import Thread
    from multiprocessing import Process, Pipe
    
    class TimedProcess(Process):
    
        daemon = True
    
        def __init__(self, *args, **kwargs):
            super(TimedProcess, self).__init__(*args, **kwargs)
            self.parent_conn, self.child_conn = Pipe()
            self.child_finished = False
            self._duration = 0.0
    
        def get_duration(self):
            if not self.child_finished:
                self.parent_conn.send(None)
                result = self.parent_conn.recv()
                if result == 'done':
                    self.child_finished = True
                else:
                    self._duration = result
            return self._duration
    
        def run(self):
            try:
                t0 = time.clock()
                Thread(target=self._run).start()
                while True:
                    request = self.child_conn.recv()
                    self.child_conn.send(time.clock() - t0)
                    if request == 'stop':
                        break
            finally:
                self.child_conn.send('done')
    
        def _run(self):
            try:
                super(TimedProcess, self).run()
            finally:
                self.parent_conn.send('stop')
    
    p = TimedProcess(target=my_long_running_func)
    p.start()
    while p.is_alive():
        time.sleep(1)
        print p.get_duration()
    

