2016-11-04 98 views
0

有沒有一種方法可以跟蹤線程是否正在運行,通過使用線程對象的某種ID /引用,所以我會知道線程是否真的在某個特定的時間運行。Python線程:甚至在應用程序重新啓動後跟蹤線程?

我有對線程模式的應用程序啓動的製造過程的功能。如果沒有服務器重新啓動並且沒有任何問題,那麼一切通常都會在後臺完成。

但是,如果例如服務器重新啓動,並且當任何線程正在運行,那麼它們會被終止,但某些命令的生成會停留在運行狀態,因爲它只在線程完成後纔會更改。

我在想一些調度會檢查這些生產訂單,如果它沒有找到相關的線程運行的生產訂單,然後它假定它是死的,必須重新啓動。

但我怎麼能使其正常軌道?

我有這樣的代碼:

from threading import Thread 

def action_produce_threaded(self): 
    thread = Thread(target=self.action_produce_thread) 
    thread.start() 
    return {'type': 'ir.actions.act_window_close'} 

def action_produce_thread(self): 
    """Threaded method to start job in background.""" 
    # Create a new database cursor. 
    new_cr = sql_db.db_connect(self._cr.dbname).cursor() 
    context = self._context 
    job = None 
    with api.Environment.manage(): 
     # Create a new environment on newly created cursor. 
     # Here we don't have a valid self.env, so we can safely 
     # assign env to self. 
     new_env = api.Environment(new_cr, self._uid, context) 
     Jobs = self.with_env(new_env).env['mrp.job'] 
     try: 
      # Create a new job and commit it. 
      # This commit is required to know that process is started. 
      job = Jobs.create({ 
       'production_id': context.get('active_id'), 
       'state': 'running', 
       'begin_date': fields.Datetime.now(), 
      }) 
      new_cr.commit() 
      # Now call base method `do_produce` in the new cursor. 
      self.with_env(new_env).do_produce() 
      # When job will be done, update state and end_date. 
      job.write({ 
       'state': 'done', 
       'end_date': fields.Datetime.now(), 
      }) 
     except Exception as e: 
      # If we are here, then we have an exception. This exception will 
      # be written to job our job record and committed changes. 
      # If job doesn't exist, then rollback all changes. 
      if job: 
       job.write({ 
        'state': 'exception', 
        'exception': e 
       }) 
       new_cr.commit() 
      new_cr.rollback() 
     finally: 
      # Here commit all transactions and close cursor. 
      new_cr.commit() 
      new_cr.close() 

所以現在在部分地方創建job,當出現錯誤時可以卡住。它將停留在'運行'狀態,因爲它不會在數據庫中更新。

我應該使用一些單獨的類,將通過他們的一生跟蹤線程,從而定期運行一些的cronjob,可以檢查一下,再決定哪些線程真的不多,哪些是意外被殺?

P.S.可能有一些很好的做法,如果是這樣,請諮詢。

+0

我認爲如果你的腳本完全被刪除了(比如說'kill -9'),你必須知道線程狀態的唯一方法是如果那些線程一直在寫他們的進步...某處(文件,數據庫...) – BorrajaX

回答

0

我可以通過編寫單獨的類來解決這個問題。現在它跟蹤活動線程,並且如果服務器重新啓動,所有對活動線程的引用都將消失,我不會再找到它(只會發現新啓動的內容)。所以我肯定知道哪些線程死了,可以安全地重啓,哪些不能。

我不知道這是否是解決這個問題的最優化的方式,但在這裏它是:

class ObjectTracker(object): 
    """Singleton class to track current live objects.""" 

    class __ObjectTracker: 
     objects = {} 

     @classmethod 
     def add_object(cls, resource, obj): 
      """Add object and resource that goes it into class dict.""" 
      cls.objects[resource] = obj 

     @classmethod 
     def get_object(cls, resource): 
      """Get object using resource as identifier.""" 
      return cls.objects.get(resource) 

     @classmethod 
     def pop_object(cls, resource): 
      """Pop object if it exists.""" 
      return cls.objects.pop(resource, None) 

    instance = None 

    def __new__(cls): 
     """Instantiate only once.""" 
     if not ObjectTracker.instance: 
      ObjectTracker.instance = ObjectTracker.__ObjectTracker() 
     return ObjectTracker.instance 

    def __getattr__(self, name): 
     """Return from singleton instance.""" 
     return getattr(self.instance, name) 

    def __setattr__(self, name): 
     """Set to singleton instance.""" 
     return setattr(self.instance, name) 

附:這被用作我的單例的開始示例:http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html#id4