2014-01-24 21 views
1

是否有一種簡單的方法來跟蹤進程以及它啓動的任何子進程的CPU時間?跟蹤Python進程和子進程的CPU時間

我試圖子類multiprocessing.Process到任意時間的功能,如:

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) 

然而,當我試圖時間函數涉及Scikits學習或其它代碼涉及的c-擴展或子工藝,我發現我的duration_sections通常會報告0或僅僅幾秒鐘,即使代碼會運行數小時。我將如何解決這個問題?

+0

檢查psutil –

+0

@CoreyGoldberg,我用,在過去的一點點。你有什麼特別的功能嗎?它似乎沒有包含明確的方法,但我可以想象從他們的'Process.get_children()'和'cpu_times()'方法構建一個方法。 – Cerin

+0

如果您希望從進程內部獲得'time.clock()'的值,那麼您將不得不將它從一個進程發送到另一個進程,例如'multiprocessing.Queue'。 –

回答

1

您的代碼幾乎打印CPU時間,但您在父進程中調用time.clock()而不是子進程。通過使用multiprocessing.Pipe,你可以從孩子值傳遞給父進程:出

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() 
+0

感謝您的代碼,但這看起來效率很低。您不需要從每個進程中獲取clock()。您可以在Linux上讀取'/ proc/stat'或'/ proc//stat'中的任何進程的用戶時間,這會更快,因爲它避免了進程間IO。 – Cerin

+0

好點,好主意。 –