`
淘气天空lc
  • 浏览: 47814 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

python守护进程编写

 
阅读更多

 

守护进程:通常被定义为一个后台进程,而且它不属于任何一个终端会话(terminal session)。许多系统服务由守护程序实施;如网络服务,打印等。 

1. 调用fork()以便父进程可以退出,这样就将控制权归还给运行你程序的命令行或shell程序。需要这一步以便保证新进程不是一个进程组头领进程(process group leader)。下一步,‘setsid()’,会因为你是进程组头领进程而失败。
 说明:当进程是会话的领头进程时setsid()调用失败并返回(-1)。setsid()调用成功后,返回新的会话的ID,调用setsid函数的进程成为新的会话的领头进程,并与其父进程的会话组和进程组脱离。由于会话对控制终端的独占性,进程同时与控制终端脱离。 (setsid() unix命令)

2. 调用‘setsid()’ 以便成为一个进程组和会话组的头领进程。由于一个控制终端与一个会话相关联,而且这个新会话还没有获得一个控制终端,我们的进程没有控制终端,这对于守护程序来说是一件好事。 

3. 再次调用‘fork()’所以父进程(会话组头领进程)可以退出。这意味着我们,一个非会话组头领进程永远不能重新获得控制终端。

4. 调用‘chdir("/")’确认我们的进程不保持任何目录于使用状态。不做这个会导致系统管理员不能卸装(umount)一个文件系统,因为它是我们的当前工作目录。 [类似的,我们可以改变当前目录至对于守护程序运行重要的文件所在目录] 

5. 调用‘umask(0)’以便我们拥有对于我们写的任何东西的完全控制。我们不知道我们继承了什么样的umask。 [这一步是可选的](译者注:这里指步骤5,因为守护程序不一定需要写文件)

6. 调用‘close()’关闭文件描述符0,1和2。这样我们释放了从父进程继承的标准输入,标准输出,和标准错误输出。我们没办法知道这些文描述符符可能 已经被重定向去哪里。注意到许多守护程序使用‘sysconf()’来确认‘_SC_OPEN_MAX’的限制。‘_SC_OPEN_MAX’告诉你每个 进程能够打开的最多文件数。然后使用一个循环,守护程序可以关闭所有可能的文件描述符。你必须决定你需要做这个或不做。如果你认为有可能有打开的文件描述 符,你需要关闭它们,因为系统有一个同时打开文件数的限制。 

7. 为标准输入,标准输出和标准错误输出建立新的文件描述符。即使你不打算使用它们,打开着它们不失为一个好主意。准确操作这些描述符是基于各自爱好;比如 说,如果你有一个日志文件,你可能希望把它作为标准输出和标准错误输出打开,而把‘/dev/null’作为标准输入打开;作为替代方法,你可以将‘ /dev/console’作为标准错误输出和/或标准输出打开,而‘/dev/null’作为标准输入,或者任何其它对你的守护程序有意义的结合方法。 (译者注:一般使用dup2函数原子化关闭和复制文件描述符。

说实话,上面这段文字看着有点云里雾里,下面看个具体的代码(我只粘贴了函数的第一部分,也是最重要的一部分,要查看整个代码,请移步到这 http://www.pythonid.com/bbs/redirect.php?tid=239&goto=lastpost& highlight=自行查看):

#encoding:utf-8
import os,sys,time
stdout = "/dev/null"
stdin = "/dev/null"
stderr = None
pidfile = "./.daemon.pid"
if pidfile:
    print("pid file alread exist!")
sys.stdout.flush()
sys.stdin.flush()
try:
    pid = os.fork()
    if pid > 0:
        sys.exit() #父进程退出只剩下子进程
except OSError,e:
    sys.stderr.write("fork #1 failed:(%d)%s\n" % (e.errno,e.strerror))
    sys.exit()
#调用‘chdir("/")’确认我们的进程不保持任何目录于使用状态。不做这个会导致系统管理员不能卸装(umount)一个文件系统,因为它是我们的当前工作目录。 [类似的,我们可以改变当前目录至对于守护程序运行重要的文件所在目录]
#改变当前进程运行目录 
os.chdir("/")
#使当前线程 拥有文件读写权限
os.umask(0)
#使子线程 脱离父线程的进程组,会话组,是子进程成为新的的头领, 进程同时与会话脱离 ,
os.setsid()
try:
    pid = os.fork() #父进程的会话头领可以退出,以为着非会话头领进程永远不可能获得终端
    if pid > 0 :
        sys.exit()
except OSError,e:
    sys.stderr.write("fork #2 failed:(%d)%s\n"  % (e.errno,e.strerror))
#调用close关闭从父进程继承过来的标准输入输出
if not stderr:
    stderr = stdout
    si = file(stdin,'r')
    so = file(stdout,'a+')
    se = file(stderr,'a+',0)#ubuffered
    pid = str(os.getpid())
    print("daemon process id:%s" % pid)
    sys.stderr.write("\n%s\n" % pid)
    sys.stderr.flush()
    if pidfile:
        abspath = os.path.abspath(pidfile)
        print(abspath)
        print("write to pid file :true")
        open(pidfile,"a").write("%s\n" % pid)
   #改变文件符号
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(),sys.stdout.fileno())  
    os.dup2(se.fileno(),sys.stderr.fileno())  
 

父进程执行代码到os.fork()处时,会将自己整个拷贝一份(即子进程)这时候父进程os.fork()的返回值大于零(即子进程的PID), 子进程os.fork()的返回值等于零,父进程结束,子进程继续执行,这时候又遇到第二个os.fork(),如上次一样,原来的子进程变成了父进程, 又产生新的子进程,之后父进程就结束。这就能够说通第一次是避免process group leader,第二次是避免session group leader。子进程就变成了一个无终端,无会话的完全自我掌控的后台进程了。

 

文章出处:http://www.oschina.net/question/163912_30297

 

分享到:
评论

相关推荐

    python编写守护进程实现当python进程被杀后重启进程的源代码

    下面是一个简单的Python守护进程示例: ```python import os import sys def daemonize(): try: # 第一次fork,创建子进程,父进程退出 pid = os.fork() if pid > 0: sys.exit(0) # 父进程退出 except ...

    Python 编写windows守护进程程序

    项目中使用python写一个监控程序,每隔5秒监控目录,发现文件就...为了谨防程序崩溃,特别编写一个守护进程程序,时刻监控程序是否崩溃并重新启动。 博文: http://blog.csdn.net/alex_bean/article/details/77923178

    python编写的WINDOWS进程守护小工具

    8. **多线程或异步编程**:为了不影响主程序的执行,守护进程的检查和恢复操作可能需要在单独的线程或异步任务中进行。Python的`threading`库或`asyncio`库可以实现这一需求。 通过以上知识点的综合运用,我们可以...

    Python-守护进程管理基类提供守护进程创建及终止日志记录子进程管理

    为了有效地管理和控制这些守护进程,开发者通常会编写一个基类来处理守护进程的启动、停止、日志记录以及子进程管理。这个"Python-守护进程管理基类提供守护进程创建及终止日志记录子进程管理"项目就是一个这样的...

    daemonize, 在 python 中,守护进程是一个编写系统守护进程的库.zip

    daemonize, 在 python 中,守护进程是一个编写系统守护进程的库 守护进程 守护程序是在 python 中编写系统守护进程的一个库。 它是在MIT许可下发布的。 最新版本可以从 PyPI 下载。 完整的文档可以在 ReadTheDocs ...

    Python守护进程(daemon)代码实例

    Python守护进程,也称为daemon,是运行在后台的程序,它们独立于控制终端并且不会在用户的登录会话中显示。守护进程通常用于提供系统服务,如网络服务、定时任务等。在Unix/Linux系统中,守护进程是系统服务的核心...

    python使用fork实现守护进程的方法

    Python中的守护进程(Daemon)是系统中一种特殊类型的进程,它们不依赖于任何终端,通常在后台运行,用于执行特定的...在编写守护进程时,还需要考虑异常处理、日志记录和资源管理等最佳实践,以确保其稳定性和可靠性。

    Python如何实现守护进程的方法示例

    要使你的python服务不受终端影响而常驻系统,就需要将它变成守护进程。 守护进程就是Daemon程序,是一种在系统后台执行的程序,它独立于控制终端并且执行一些周期任务或触发事件,通常被命名为”d”字母结尾,如...

    守护进程批处理

    创建守护进程通常涉及编写shell脚本(如bash)或用C、Python等编程语言编写。Linux中的一些常用工具,如systemd或init,可以帮助管理守护进程的生命周期。 例如,一个名为"守护进程1.sh"的Linux脚本可以通过以下...

    使用Python编写Linux系统守护进程实例

    这个简单的Python守护进程示例展示了如何在Python中实现基本的守护进程特性。实际应用中,你可能还需要考虑其他因素,比如日志管理、资源限制、异常处理和守护进程的启动、停止、重启等操作。通过理解和实践这些基础...

    python实现的守护进程(Daemon)用法实例

    在Python中,实现守护进程的方式多种多样,但这里我们关注的是通过自定义函数来创建守护进程的方法。 在给出的代码实例中,`createDaemon()` 函数负责将当前进程转化为守护进程。这个函数的核心步骤如下: 1. **第...

    Python守护进程实现过程详解

    Python守护进程(Daemon)是操作系统中的一个概念,它是指一种在后台运行并不受终端控制的进程。在Python中,线程也有类似的概念,一个守护线程(Daemon Thread)是在主程序退出时不需要等待其完成即可结束的线程。...

    Python多进程例子代码.zip_Python多进程例子代码_py代码过长_py多进程

    在`Python多进程例子代码`这个压缩包中,可能包含了各种多进程编程的例子,比如进程间通信(使用`Queue`、`Pipe`等)、守护进程(`daemon`属性)、进程池的使用等。这些例子可以帮助初学者更好地理解多进程编程的...

    Python实现Linux下守护进程的编写方法

    本文实例讲述了Python实现Linux下守护进程的编写方法,分享给大家供大家参考,相信对于大家的Python程序设计会起到一定的帮助作用。具体方法如下: 1. 调用fork()以便父进程可以退出,这样就将控制权归还给运行你...

    Python高级编程-Python多进程编程基础及实例讲解 共14页.pdf

    守护进程在所有非守护进程结束后自动结束。 `join()`方法用于等待进程结束,通常用在父进程需要知道子进程何时完成的场景。默认情况下,`join()`会一直阻塞直到进程结束,但也可以设置`timeout`参数,如: ```...

    python并发编程多进程之守护进程原理解析

    总结一下,Python的并发编程多进程通过守护进程可以实现主进程退出后子进程依然运行的场景,但要注意守护进程不能创建子进程这一限制。在实际编写代码时,务必在启动子进程前将其设置为守护进程,以确保程序的行为...

    linux守护进程随系统启动而启动

    本教程将详细介绍在Debian、Red Hat和Ubuntu系统下,如何编写和配置守护进程,使其随系统启动而启动。 首先,我们需要编写守护进程程序。在Linux环境下,通常使用C、Python、Perl或其他支持后台运行的编程语言来...

    daemonize, 编写系统守护进程的库.zip

    daemonize, 编写系统守护进程的库 守护进程 守护进程是一个编写系统守护进程的库。 由 python 库 thesharp/守护进程激发。用法示例:extern crate daemonize;use std::fs::File;u

Global site tag (gtag.js) - Google Analytics