zoukankan      html  css  js  c++  java
  • A daemon process class in python

    In everbright task schedule project, we need some daemon process to do certain work, here is a example of daemon class:

      1 #encoding=utf-8
      2 #!/usr/bin/env python
      3 
      4 import sys, os, time, atexit
      5 from signal import SIGTERM 
      6 Basedir='/home/ronglian/project/taskschedule'
      7 class Daemon:
      8     """
      9     A generic daemon class.
     10     
     11     Usage: subclass the Daemon class and override the run() method
     12     """
     13     def __init__(self, pidfile, stderr=Basedir+'/logs/deamon_err.log', stdout=Basedir+'/logs/deamon_out.log', stdin='/dev/null'):
     14         self.stdin = stdin
     15         self.stdout = stdout
     16         self.stderr = stderr
     17         self.pidfile = pidfile
     18     
     19     def daemonize(self):
     20         """
     21         do the UNIX double-fork magic, see Stevens' "Advanced 
     22         Programming in the UNIX Environment" for details (ISBN 0201563177)
     23         http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
     24         """
     25         try: 
     26             pid = os.fork() 
     27             if pid > 0:
     28                 # exit first parent
     29                 sys.exit(0) 
     30         except OSError, e: 
     31             sys.stderr.write("fork #1 failed: %d (%s)
    " % (e.errno, e.strerror))
     32             sys.exit(1)
     33     
     34         # decouple from parent environment
     35         os.chdir("/") 
     36         os.setsid() 
     37         os.umask(0) 
     38     
     39         # do second fork
     40         try: 
     41             pid = os.fork() 
     42             if pid > 0:
     43                 # exit from second parent
     44                 sys.exit(0) 
     45         except OSError, e: 
     46             sys.stderr.write("fork #2 failed: %d (%s)
    " % (e.errno, e.strerror))
     47             sys.exit(1) 
     48     
     49         # redirect standard file descriptors
     50         sys.stdout.flush()
     51         sys.stderr.flush()
     52         si = file(self.stdin, 'r')
     53         so = file(self.stdout, 'a+')
     54         se = file(self.stderr, 'a+', 0)
     55         os.dup2(si.fileno(), sys.stdin.fileno())
     56         os.dup2(so.fileno(), sys.stdout.fileno())
     57         os.dup2(se.fileno(), sys.stderr.fileno())
     58     
     59         # write pidfile
     60         atexit.register(self.delpid)
     61         pid = str(os.getpid())
     62         file(self.pidfile,'w+').write("%s
    " % pid)
     63     
     64     def delpid(self):
     65         os.remove(self.pidfile)
     66 
     67     def start(self):
     68         """
     69         Start the daemon
     70         """
     71         # Check for a pidfile to see if the daemon already runs
     72         try:
     73             pf = file(self.pidfile,'r')
     74             pid = int(pf.read().strip())
     75             pf.close()
     76         except IOError:
     77             pid = None
     78     
     79         if pid:
     80             message = "pidfile %s already exist. Daemon already running?
    "
     81             sys.stderr.write(message % self.pidfile)
     82             sys.exit(1)
     83         
     84         # Start the daemon
     85         self.daemonize()
     86         self.run()
     87 
     88     def stop(self):
     89         """
     90         Stop the daemon
     91         """
     92         # Get the pid from the pidfile
     93         try:
     94             pf = file(self.pidfile,'r')
     95             pid = int(pf.read().strip())
     96             pf.close()
     97         except IOError:
     98             pid = None
     99     
    100         if not pid:
    101             message = "pidfile %s does not exist. Daemon not running?
    "
    102             sys.stderr.write(message % self.pidfile)
    103             return # not an error in a restart
    104 
    105         # Try killing the daemon process    
    106         try:
    107             while 1:
    108                 os.kill(pid, SIGTERM)
    109                 time.sleep(0.1)
    110         except OSError, err:
    111             err = str(err)
    112             if err.find("No such process") > 0:
    113                 if os.path.exists(self.pidfile):
    114                     os.remove(self.pidfile)
    115             else:
    116                 print str(err)
    117                 sys.exit(1)
    118 
    119     def restart(self):
    120         """
    121         Restart the daemon
    122         """
    123         self.stop()
    124         self.start()
    125 
    126     def run(self):
    127         """
    128         You should override this method when you subclass Daemon. It will be called after the process has been
    129         daemonized by start() or restart().
    130         """

    Here is a example how to use the class, need to rewrite the run function in parent calss:

     1 #encoding=utf-8
     2 
     3 import sys, time
     4 from daemon import Daemon
     5 import dbaction
     6 import Task
     7 import getdependency
     8 from  tslogging import GlobalLogging as Logging
     9 
    10 class sys_sync_task_mgr(Daemon):
    11     def __init__(self,temppath,starttime,frequency):
    12         Daemon.__init__(self,temppath)
    13         self.starttime = starttime
    14         self.frequency = frequency
    15 
    16     def run(self):
    17 
    18         
    19         while True:
    20             tasknolist= self.get_task_list()
    21             
    22             if len(tasknolist['sys_task']) > 0:
    23                 if time.ctime()>self.starttime:
    24                     Logging.getLog().info('Available system task list:%s'%(str(tasknolist['sys_task'])))
    25                     try:
    26                         for taskno in tasknolist['sys_task']:
    27                             Logging.getLog().info('Start running system task:%s'%str(taskno))
    28                             task = Task.sys_sync_task(taskno)
    29                             task.task_run()
    30                     except Exception, ex:
    31                         print 'hello'
    32                         Logging.getLog().error( "Exception in class: 'sys_sync_task_mgr' function:'run' :"+str(ex))
    33                 else:
    34                     print 'hello'
    35                     Logging.getLog().warn('Time to run the tasks still not reach.')
    36             time.sleep(self.frequency)
    37     def get_task_list(self):
    38         tasklist = getdependency.task_dependency([],3,1).get_executable_task()
    39         return tasklist
    40 
    41 #main function        
    42 if __name__ == "__main__":
    43     daemon = sys_sync_task_mgr('/tmp/daemon_sys_sync_task_mgr.pid',time.ctime(),20)
    44     if len(sys.argv) == 2:
    45         if 'start' == sys.argv[1]:
    46             daemon.start()
    47         elif 'stop' == sys.argv[1]:
    48             daemon.stop()
    49         elif 'restart' == sys.argv[1]:
    50             daemon.restart()
    51         else:
    52             print "Unknown command"
    53             sys.exit(2)
    54         sys.exit(0)
    55     else:
    56         print "usage: %s start|stop|restart" % sys.argv[0]
    57         sys.exit(2)
  • 相关阅读:
    php将字符串形式的数组转化为真数组
    Mysql8.0及以上 only_full_group_by以及其他关于sql_mode原因报错详细解决方案
    php使用base64_encode和base64_decode对数据进行编码和解码
    大数据基本概念
    sonarqube安装部署
    git-修改commit信息
    NLP-Commen Sense
    索引生命周期的管理
    kibana软件具体参数配置信息
    es机器监控x-pack导致的监控存储过大的问题
  • 原文地址:https://www.cnblogs.com/allenz/p/4756111.html
Copyright © 2011-2022 走看看