用于编写守护进程的框架,API类似于线程和进程模块。
项目描述
混乱之地
混乱之地为Python编写守护进程提供了一个框架。API基于threading/multiprocessing模型,因此创建自己的守护进程的主要方式是子类化并覆盖run
方法,或者提供一个函数作为Daemon
类的target
。
除了Daemon
之外,还有一个锁定pid文件:PidLockFile
。可以手动使用PidLockFile
,如果为Daemon
提供了完整路径和文件名,则可以自动使用。
简单用法
from pandaemonium import Daemon
def DoSomethingInteresting():
"Just like it says ;)"
pass
daemon = Daemon(target=DoSomethingInteresting)
daemon.start()
#
# daemon.output will contain any stdout output generated during the
# daemonizing process, up to the stdin/stdout/stderr redirection
#
# daemon.error contains anything sent to the daemon's stderr -- which
# most likely means the daemon died due to an exception
#
# both can be parsed, examined, ignored, etc.
或
from pandaemonium import Daemon
class MyDaemon(Daemon):
def run():
# do some interesting stuff
md = MyDaemon().start()
调用start()
时发生的事件序列(改编自Michael Kerrisk的《Linux编程接口》)是
- 从当前进程分离,创建新会话
- 关闭核心转储
- 设置uid和gid
- 设置umask
- 设置工作目录
- 创建pid文件
- 设置信号处理器
- 关闭继承的文件句柄
- 重定向stdin/stdout/stderr
如果在start
过程中发生任何异常或生成任何反馈,它将作为守护进程实例的error
和output
属性可用,在父进程退出之前可以分析、打印等。
注意:大多数关于编写守护进程的指南都指定将umask设置为0,但这会创建一个安全漏洞,因为所有文件默认情况下都对外部世界可读/可写。Pandaemonium将umask设置为077,但可以根据需要更改。
高级用法
如果需要比守护进程参数提供更多的控制,则有一些选项可供选择
-
如果某些设置/初始化步骤需要在
start()
序列中的某个地方发生,例如在设置umask和更改工作目录之前:Daemon.stage4() # stages 1-4 have now been completed # do custom steps here Daemon.start() # stages 5-9 have now been completed, and run() called
-
也可以在子类中覆盖任何阶段(确保用
check_stage
装饰器装饰)class MyDaemon(Daemon): def run(self, ip): # do stuff @check_stage def stage7(self): # do some custom stuff with signals set up md = MyDaemon('192.168.11.1') md.start()
-
或者,为了简化前台和守护进程操作
foreground = sys.argv[2:3] == ['--foreground'] pid_file = PidLockFile('/some/path/to/lock.pid') pid_file.acquire() if foreground: pid_file.seal() else: daemon = Daemon() daemon.pid_file = pid_file daemon.activate() # at this point, in either foreground or daemon mode, the pid file has # been sealed (has our correct pid written to it, and it has been # closed) run_main_program()
如果希望启动守护进程并且自动将任何输出打印到屏幕,可以使用daemon.report()
,它将打印从守护进程接收到的任何内容,然后退出。
守护进程
Daemon
(target=None, args=None, kwargs=None, working_directory='/', umask=0, prevent_core=True, process_ids=None, inherit_files=None, signal_map=None, stdin=None, stdout=None, stderr=None)
-
target:在守护进程化时调用的函数
-
args:提供给目标的位置参数
-
kwargs:提供给目标的键参数
-
detach:
None
(默认)表示找出它,True
表示是,False
表示否。找出它意味着如果父进程是init
或超级服务器,则不分离 -
working_directory:要更改到的目录(相对于chroot,如果有作用的话)
-
umask:创建文件时要使用的掩码
-
prevent_core:防止创建核心转储文件
-
process_ids:要切换到进程的(uid,gid)元组(使用(None,None)来禁用)
-
pid_file:
None
(默认),或PidLockFile实例,或创建PidLockFile的字符串 -
inherit_files:要保留打开的文件或文件描述符的列表
-
signal_map:信号名称或数字到方法名称或函数的字典
-
stdin / stdout / stderr:将标准流映射到流。默认为
None
,映射到os.devnull
Daemon.run()
Daemon.run()
表示守护进程活动的方法。
可以在子类中重写此方法。标准的run
方法将对象构造函数作为target
参数传递的可调用对象调用,如果有的话,并分别使用从args
和kwargs
参数获取的顺序和关键字参数。
Daemon.start()
Daemon.start()
启动守护进程活动。
这最多可以在每个守护进程对象上调用一次。它安排对象的run
方法作为守护进程进程被调用。
Daemon.monitor()
Daemon.monitor()
从守护进程进程收集stdout和stderr,直到阶段9,并将其附加到守护进程实例上的output
和error
。如果想要对守护进程的输出做更多有趣的事情,可以重写它
Daemon.stage[1-9]()
Daemon.stage[1-9]()
可以覆盖各种阶段以获得更多的自定义选项。确保用check_stage
装饰这样的函数。
PidLockFile
PidLockFile
(file_name, timeout)
-
file_name:用于锁定的完整路径和文件名
-
timeout:在得出现有保留锁不会释放的结论之前等待多长时间(默认:-1,表示立即得出结论)
PidLockFile.acquire(timeout=None)
PidLockFile.acquire(timeout=None)
尝试捕获锁文件;如果timeout为None
,则使用在创建PidLockFile时指定的超时时间。
PidLockFile.seal()
PidLockFile.seal()
将当前进程的PID写入获取的文件并关闭它--应只由守护进程进程或存储的PID将不会正确。
PidLockFile.release()
PidLockFile.release()
删除锁文件,释放锁。
项目详细信息
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。