自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用python做服務(wù)端時實現(xiàn)守候進程的那些方式

開發(fā) 后端 前端
這是我寫的關(guān)于 daemonize demo例子,大家可以直接跑跑。 之后,可以看到,我雖然死循環(huán)了,但是后臺的服務(wù)器還是一直跑著,可以通過進程的狀態(tài),或者是通過daemonize本身的函數(shù)接口獲取狀態(tài)。

說說,需要做守候進程的時候,我是怎么進化高端的。(怎么高端,具體自己定義,我的土,說不定是你的高端)

python deamon的思路:

1.進程脫離父進程及終端綁定,如果不這樣的話,主進程退出,派生的子進程也跟著倒霉了。脫離終端也是這個理。

2.進程唯一性保證,這是廢話

3.標準輸入/輸出/錯誤重定向,為了不讓錯誤打到前面,又為了更好的分析數(shù)據(jù)。

說的洋氣點、nb點、細化點(其實就os的三個動作):

os.chdir("/")  將當前工作目錄更改為根目錄。從父進程繼承過來的當前工作目錄可能在一個裝配的文件系統(tǒng)中。

os.setsid() 調(diào)用 setsid 以創(chuàng)建一個新對話期,創(chuàng)建了一個獨立于當前會話的進程。

os.umask(0) 重設(shè)文件創(chuàng)建掩碼,子進程會從父進程繼承所有權(quán)限,可以通過調(diào)用這個方法將文件創(chuàng)建掩碼初始化成系統(tǒng)默認。

記得最一開始,用的還是shell的手段,nohup 重定向到一個log文件里面。  具體怎么用,我估計大家都懂。

nohup xxxx  xxxx &

緊接著用python的subprocess模塊,來fork daemon進程,然后自己退出來。  這樣也是實現(xiàn)了守候進程。 subprocess  派生了子進程后,他還是可以有效的控制子進程,比如kill,掛起。

  1. import subprocess   
  2. #xiaorui.cc   
  3. from subprocess import call   
  4. f=open("/dev/null",'r')   
  5. proc=subprocess.Popen(xxx, shell=True,stdout=f,executable='/bin/bash')   
  6. f.close 

學(xué)習(xí)python的服務(wù)端一大利器 twisted的時候,他本身也可以做守候進程的。當然方法有些局限,僅僅適合依照twisted為左右的網(wǎng)絡(luò)編程。

  1. #!/usr/bin/twistd -y   
  2. #xiaorui.cc   
  3. from twisted.application import service, internet   
  4. from twisted.internet import reactor   
  5. import time   
  6. import os,sys   
  7. i=0 
  8. def writedata():   
  9.     global i   
  10.     i+=1 
  11.     a=i   
  12.     print 'waiting to write data     (%d)'%a   
  13.     time.sleep(8)   
  14.     print 'writing data!!!!         (%d)'%a   
  15.     while True:   
  16.         time.sleep(0.2)   
  17.         aa=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())   
  18.         os.system("echo %s >>log"%aa)   
  19.     
  20.     
  21. def writeinthread():   
  22.     reactor.callInThread(writedata)   
  23.     
  24.     
  25. application =service.Application('timeserver')   
  26. tservice = internet.TimerService(10000,writeinthread)   
  27. tservice.setServiceParent(application ) 

上面介紹了很多的方法,但是不管是python、golang、ruby社區(qū)用supervisor做進程管理的居多。原因,夠簡單,夠直白。 supervisor配置文件是相當?shù)呢S富,他還有supervisorctl 終端管理器,更有web 管理界面 。 對我來說,supervisor tornado 絕配。

這段時間找到了一個好模塊,pip install daemonize

這是我寫的關(guān)于 daemonize demo例子,大家可以直接跑跑。 之后,可以看到,我雖然死循環(huán)了,但是后臺的服務(wù)器還是一直跑著,可以通過進程的狀態(tài),或者是通過daemonize本身的函數(shù)接口獲取狀態(tài)。

  1. #xiaorui.cc   
  2. from time import sleep   
  3. import os,sys   
  4. from daemonize import Daemonize   
  5.     
  6. pid = "/tmp/test.pid" 
  7.     
  8. def wlog():   
  9.     f=open('/tmp/nima','a')   
  10.     f.write('11')   
  11.     f.close()   
  12.     
  13. def main():   
  14.     while True:   
  15.         sleep(5)   
  16.         wlog()   
  17.     
  18. daemon = Daemonize(app="test_app", pid=pid, action=main)   
  19. daemon.start()   
  20. daemon.get_pid()   
  21. daemon.is_running() 

wKioL1OXLQ-RQcz9AAYYBVybewQ020.jpg

他的源碼實現(xiàn)方式:

不多說了,就是fork fork fork ....

  1. # Core modules   
  2. import atexit   
  3. import os   
  4. import sys   
  5. import time   
  6. import signal   
  7.     
  8.     
  9. class Daemon(object):   
  10.     """   
  11.     A generic daemon class.   
  12.     
  13.     Usage: subclass the Daemon class and override the run() method   
  14.     """ 
  15.     def __init__(self, pidfile, stdin=os.devnull,   
  16.                  stdout=os.devnull, stderr=os.devnull,   
  17.                  home_dir='.', umask=022, verbose=1):   
  18.         self.stdin = stdin   
  19.         self.stdout = stdout   
  20.         self.stderr = stderr   
  21.         self.pidfile = pidfile   
  22.         self.home_dir = home_dir   
  23.         self.verbose = verbose   
  24.         self.umask = umask   
  25.         self.daemon_alive = True 
  26.     
  27.     def daemonize(self):   
  28.         """   
  29.         Do the UNIX double-fork magic, see Stevens' "Advanced   
  30.         Programming in the UNIX Environment" for details (ISBN 0201563177)   
  31.         http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16   
  32.         """ 
  33.         try:   
  34.             pid = os.fork()   
  35.             if pid > 0:   
  36.                 # Exit first parent   
  37.                 sys.exit(0)   
  38.         except OSError, e:   
  39.             sys.stderr.write(   
  40.                 "fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))   
  41.             sys.exit(1)   
  42.     
  43.         # Decouple from parent environment   
  44.         os.chdir(self.home_dir)   
  45.         os.setsid()   
  46.         os.umask(self.umask)   
  47.     
  48.         # Do second fork   
  49.         try:   
  50.             pid = os.fork()   
  51.             if pid > 0:   
  52.                 # Exit from second parent   
  53.                 sys.exit(0)   
  54.         except OSError, e:   
  55.             sys.stderr.write(   
  56.                 "fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))   
  57.             sys.exit(1)   
  58.     
  59.         if sys.platform != 'darwin':  # This block breaks on OS X   
  60.             # Redirect standard file descriptors   
  61.             sys.stdout.flush()   
  62.             sys.stderr.flush()   
  63.             si = file(self.stdin, 'r')   
  64.             so = file(self.stdout, 'a+')   
  65.             if self.stderr:   
  66.                 se = file(self.stderr, 'a+'0)   
  67.             else:   
  68.                 se = so   
  69.             os.dup2(si.fileno(), sys.stdin.fileno())   
  70.             os.dup2(so.fileno(), sys.stdout.fileno())   
  71.             os.dup2(se.fileno(), sys.stderr.fileno())   
  72.     
  73.         def sigtermhandler(signum, frame):   
  74.             self.daemon_alive = False 
  75.             signal.signal(signal.SIGTERM, sigtermhandler)   
  76.             signal.signal(signal.SIGINT, sigtermhandler)   
  77.     
  78.         if self.verbose >= 1:   
  79.             print "Started" 
  80.     
  81.         # Write pidfile   
  82.         atexit.register(   
  83.             self.delpid)  # Make sure pid file is removed if we quit   
  84.         pid = str(os.getpid())   
  85.         file(self.pidfile, 'w+').write("%s\n" % pid)   
  86.     
  87.     def delpid(self):   
  88.         os.remove(self.pidfile)   
  89.     
  90.     def start(self, *args, **kwargs):   
  91.         """   
  92.         Start the daemon   
  93.         """ 
  94.     
  95.         if self.verbose >= 1:   
  96.             print "Starting..." 
  97.     
  98.         # Check for a pidfile to see if the daemon already runs   
  99.         try:   
  100.             pf = file(self.pidfile, 'r')   
  101.             pid = int(pf.read().strip())   
  102.             pf.close()   
  103.         except IOError:   
  104.             pid = None 
  105.         except SystemExit:   
  106.             pid = None 
  107.     
  108.         if pid:   
  109.             message = "pidfile %s already exists. Is it already running?\n" 
  110.             sys.stderr.write(message % self.pidfile)   
  111.             sys.exit(1)   
  112.     
  113.         # Start the daemon   
  114.         self.daemonize()   
  115.         self.run(*args, **kwargs)   
  116.     
  117.     def stop(self):   
  118.         """   
  119.         Stop the daemon   
  120.         """ 
  121.     
  122.         if self.verbose >= 1:   
  123.             print "Stopping..." 
  124.     
  125.         # Get the pid from the pidfile   
  126.         pid = self.get_pid()   
  127.     
  128.         if not pid:   
  129.             message = "pidfile %s does not exist. Not running?\n" 
  130.             sys.stderr.write(message % self.pidfile)   
  131.     
  132.             # Just to be sure. A ValueError might occur if the PID file is   
  133.             # empty but does actually exist   
  134.             if os.path.exists(self.pidfile):   
  135.                 os.remove(self.pidfile)   
  136.     
  137.             return  # Not an error in a restart   
  138.     
  139.         # Try killing the daemon process   
  140.         try:   
  141.             i = 0 
  142.             while 1:   
  143.                 os.kill(pid, signal.SIGTERM)   
  144.                 time.sleep(0.1)   
  145.                 i = i + 1 
  146.                 if i % 10 == 0:   
  147.                     os.kill(pid, signal.SIGHUP)   
  148.         except OSError, err:   
  149.             err = str(err)   
  150.             if err.find("No such process") > 0:   
  151.                 if os.path.exists(self.pidfile):   
  152.                     os.remove(self.pidfile)   
  153.             else:   
  154.                 print str(err)   
  155.                 sys.exit(1)   
  156.     
  157.         if self.verbose >= 1:   
  158.             print "Stopped" 
  159.     
  160.     def restart(self):   
  161.         """   
  162.         Restart the daemon   
  163.         """ 
  164.         self.stop()   
  165.         self.start()   
  166.     
  167.     def get_pid(self):   
  168.         try:   
  169.             pf = file(self.pidfile, 'r')   
  170.             pid = int(pf.read().strip())   
  171.             pf.close()   
  172.         except IOError:   
  173.             pid = None 
  174.         except SystemExit:   
  175.             pid = None 
  176.         return pid   
  177.     
  178.     def is_running(self):   
  179.         pid = self.get_pid()   
  180.         print(pid)   
  181.         return pid and os.path.exists('/proc/%d' % pid)   
  182.     
  183.     def run(self):   
  184.         """   
  185.         You should override this method when you subclass Daemon.   
  186.         It will be called after the process has been   
  187.         daemonized by start() or restart().   
  188.         """ 

使用python做守候進程服務(wù),不知道還有沒有更好點、更霸道的方法。大家有的話,要分享下,咱們一塊交流下 ....

博客原文:http://rfyiamcool.blog.51cto.com/1030776/1424809

責任編輯:林師授 來源: 51CTO博客
相關(guān)推薦

2022-05-08 17:53:38

Nacos服務(wù)端客戶端

2024-01-02 13:58:04

GoREST API語言

2011-09-09 09:44:23

WCF

2010-02-24 15:42:03

WCF服務(wù)端安全

2015-11-09 17:51:12

服務(wù)器端開發(fā)

2016-03-18 09:04:42

swift服務(wù)端

2024-11-21 15:48:50

2009-08-21 15:36:41

服務(wù)端與客戶端

2009-08-21 15:54:40

服務(wù)端與客戶端

2010-05-28 10:10:49

2021-03-04 11:37:13

Python服務(wù)端urllib

2012-03-02 10:38:33

MySQL

2013-03-25 10:08:44

PHPWeb

2009-08-21 14:25:23

C#異步傳輸字符串

2010-03-19 18:17:17

Java Server

2024-03-14 11:48:44

系統(tǒng)監(jiān)控指標分布式

2024-05-27 00:00:00

PHP阿里云OSS

2024-01-16 08:05:53

2022-10-08 00:01:00

ssrvuereact

2024-03-06 14:58:52

客戶端微服務(wù)架構(gòu)
點贊
收藏

51CTO技術(shù)棧公眾號