2016-11-04 76 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