说说,需要做守候进程的时候,我是怎么进化高端的。(怎么高端,具体自己定义,我的土,说不定是你的高端)

成都创新互联公司从2013年成立,先为湘乡等服务建站,湘乡等地企业,进行企业商务咨询服务。为湘乡企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
python deamon的思路:
1.进程脱离父进程及终端绑定,如果不这样的话,主进程退出,派生的子进程也跟着倒霉了。脱离终端也是这个理。
2.进程唯一性保证,这是废话
3.标准输入/输出/错误重定向,为了不让错误打到前面,又为了更好的分析数据。
说的洋气点、nb点、细化点(其实就os的三个动作):
os.chdir("/") 将当前工作目录更改为根目录。从父进程继承过来的当前工作目录可能在一个装配的文件系统中。
os.setsid() 调用 setsid 以创建一个新对话期,创建了一个独立于当前会话的进程。
os.umask(0) 重设文件创建掩码,子进程会从父进程继承所有权限,可以通过调用这个方法将文件创建掩码初始化成系统默认。
记得最一开始,用的还是shell的手段,nohup 重定向到一个log文件里面。 具体怎么用,我估计大家都懂。
nohup xxxx xxxx &
紧接着用python的subprocess模块,来fork daemon进程,然后自己退出来。 这样也是实现了守候进程。 subprocess 派生了子进程后,他还是可以有效的控制子进程,比如kill,挂起。
- import subprocess
 - #xiaorui.cc
 - from subprocess import call
 - f=open("/dev/null",'r')
 - proc=subprocess.Popen(xxx, shell=True,stdout=f,executable='/bin/bash')
 - f.close
 
学习python的服务端一大利器 twisted的时候,他本身也可以做守候进程的。当然方法有些局限,仅仅适合依照twisted为左右的网络编程。
- #!/usr/bin/twistd -y
 - #xiaorui.cc
 - from twisted.application import service, internet
 - from twisted.internet import reactor
 - import time
 - import os,sys
 - i=0
 - def writedata():
 - global i
 - i+=1
 - a=i
 - print 'waiting to write data (%d)'%a
 - time.sleep(8)
 - print 'writing data!!!! (%d)'%a
 - while True:
 - time.sleep(0.2)
 - aa=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
 - os.system("echo %s >>log"%aa)
 - def writeinthread():
 - reactor.callInThread(writedata)
 - application =service.Application('timeserver')
 - tservice = internet.TimerService(10000,writeinthread)
 - tservice.setServiceParent(application )
 
上面介绍了很多的方法,但是不管是python、golang、ruby社区用supervisor做进程管理的居多。原因,够简单,够直白。 supervisor配置文件是相当的丰富,他还有supervisorctl 终端管理器,更有web 管理界面 。 对我来说,supervisor tornado 绝配。
这段时间找到了一个好模块,pip install daemonize
这是我写的关于 daemonize demo例子,大家可以直接跑跑。 之后,可以看到,我虽然死循环了,但是后台的服务器还是一直跑着,可以通过进程的状态,或者是通过daemonize本身的函数接口获取状态。
- #xiaorui.cc
 - from time import sleep
 - import os,sys
 - from daemonize import Daemonize
 - pid = "/tmp/test.pid"
 - def wlog():
 - f=open('/tmp/nima','a')
 - f.write('11')
 - f.close()
 - def main():
 - while True:
 - sleep(5)
 - wlog()
 - daemon = Daemonize(app="test_app", pid=pid, action=main)
 - daemon.start()
 - daemon.get_pid()
 - daemon.is_running()
 
他的源码实现方式:
不多说了,就是fork fork fork ....
- # Core modules
 - import atexit
 - import os
 - import sys
 - import time
 - import signal
 - class Daemon(object):
 - """
 - A generic daemon class.
 - Usage: subclass the Daemon class and override the run() method
 - """
 - def __init__(self, pidfile, stdin=os.devnull,
 - stdout=os.devnull, stderr=os.devnull,
 - home_dir='.', umask=022, verbose=1):
 - self.stdin = stdin
 - self.stdout = stdout
 - self.stderr = stderr
 - self.pidfile = pidfile
 - self.home_dir = home_dir
 - self.verbose = verbose
 - self.umask = umask
 - self.daemon_alive = True
 - def daemonize(self):
 - """
 - Do the UNIX double-fork magic, see Stevens' "Advanced
 - Programming in the UNIX Environment" for details (ISBN 0201563177)
 - http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
 - """
 - try:
 - pid = os.fork()
 - if pid > 0:
 - # Exit first parent
 - sys.exit(0)
 - except OSError, e:
 - sys.stderr.write(
 - "fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
 - sys.exit(1)
 - # Decouple from parent environment
 - os.chdir(self.home_dir)
 - os.setsid()
 - os.umask(self.umask)
 - # Do second fork
 - try:
 - pid = os.fork()
 - if pid > 0:
 - # Exit from second parent
 - sys.exit(0)
 - except OSError, e:
 - sys.stderr.write(
 - "fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
 - sys.exit(1)
 - if sys.platform != 'darwin': # This block breaks on OS X
 - # Redirect standard file descriptors
 - sys.stdout.flush()
 - sys.stderr.flush()
 - si = file(self.stdin, 'r')
 - so = file(self.stdout, 'a+')
 - if self.stderr:
 - se = file(self.stderr, 'a+', 0)
 - else:
 - se = so
 - os.dup2(si.fileno(), sys.stdin.fileno())
 - os.dup2(so.fileno(), sys.stdout.fileno())
 - os.dup2(se.fileno(), sys.stderr.fileno())
 - def sigtermhandler(signum, frame):
 - self.daemon_alive = False
 - signal.signal(signal.SIGTERM, sigtermhandler)
 - signal.signal(signal.SIGINT, sigtermhandler)
 - if self.verbose >= 1:
 - print "Started"
 - # Write pidfile
 - atexit.register(
 - self.delpid) # Make sure pid file is removed if we quit
 - pid = str(os.getpid())
 - file(self.pidfile, 'w+').write("%s\n" % pid)
 - def delpid(self):
 - os.remove(self.pidfile)
 - def start(self, *args, **kwargs):
 - """
 - Start the daemon
 - """
 - if self.verbose >= 1:
 - print "Starting..."
 - # Check for a pidfile to see if the daemon already runs
 - try:
 - pf = file(self.pidfile, 'r')
 - pid = int(pf.read().strip())
 - pf.close()
 - except IOError:
 - pid = None
 - except SystemExit:
 - pid = None
 - if pid:
 - message = "pidfile %s already exists. Is it already running?\n"
 - sys.stderr.write(message % self.pidfile)
 - sys.exit(1)
 - # Start the daemon
 - self.daemonize()
 - self.run(*args, **kwargs)
 - def stop(self):
 - """
 - Stop the daemon
 - """
 - if self.verbose >= 1:
 - print "Stopping..."
 - # Get the pid from the pidfile
 - pid = self.get_pid()
 - if not pid:
 - message = "pidfile %s does not exist. Not running?\n"
 - sys.stderr.write(message % self.pidfile)
 - # Just to be sure. A ValueError might occur if the PID file is
 - # empty but does actually exist
 - if os.path.exists(self.pidfile):
 - os.remove(self.pidfile)
 - return # Not an error in a restart
 - # Try killing the daemon process
 - try:
 - i = 0
 - while 1:
 - os.kill(pid, signal.SIGTERM)
 - time.sleep(0.1)
 - i = i + 1
 - if i % 10 == 0:
 - os.kill(pid, signal.SIGHUP)
 - except OSError, err:
 - err = str(err)
 - if err.find("No such process") > 0:
 - if os.path.exists(self.pidfile):
 - os.remove(self.pidfile)
 - else:
 - print str(err)
 - sys.exit(1)
 - if self.verbose >= 1:
 - print "Stopped"
 - def restart(self):
 - """
 - Restart the daemon
 - """
 - self.stop()
 - self.start()
 - def get_pid(self):
 - try:
 - pf = file(self.pidfile, 'r')
 - pid = int(pf.read().strip())
 - pf.close()
 - except IOError:
 - pid = None
 - except SystemExit:
 - pid = None
 - return pid
 - def is_running(self):
 - pid = self.get_pid()
 - print(pid)
 - return pid and os.path.exists('/proc/%d' % pid)
 - def run(self):
 - """
 - You should override this method when you subclass Daemon.
 - It will be called after the process has been
 - daemonized by start() or restart().
 - """
 
使用python做守候进程服务,不知道还有没有更好点、更霸道的方法。大家有的话,要分享下,咱们一块交流下 ....
博客原文:http://rfyiamcool.blog./1030776/1424809
                网页题目:用python做服务端时实现守候进程的那些方式
                
                网页链接:http://www.csdahua.cn/qtweb/news2/397652.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网