为了账号安全,请及时绑定邮箱和手机立即绑定

Python创建daemon

标签:
Python


    参考《Linux/Unix 系统编程手册》

    变成daemon,一个程序需要完成以下步骤:

    1、执行一个fork(),父进程退出,子进程继续执行。(daemon成为了init进程的子进程)  

    --假设daemon是从命令行启动,父进程的终止会被shell发现,之后shell会显示出另一个shell提示符并让子进程在后台运行;

    --子进程被确保不会成为一个进程组的首进程(它从父进程继承了进程组ID,并拥有了自己唯一的进程ID,该进程ID与继承来的进程组ID是不同的,这样才能成功执行下面一个步骤)

    2、子进程调用setsid()开启一个新会话并释放它与控制终端之间的所有关联;

    3、对于终端设备的处理:

    --daemon从未打开过终端设备,不需做任何处理;

    --daemon后面可能会打开一个终端设备,必须采取措施确保该设备不会成为控制终端,具体措施:

      1、在所有可能应用到一个终端设备上的open() 调用中指定O_NOCTTY标记;

      2、在setsid()调用之后执行第二个fork(),再次让父进程退出并让孙子进程继续执行,(这样确保了子进程不会成为会话组长,进程永远不会重新请求一个控制终端--根据SystemV中获取终端规则)

    4、清除进程的umask(确保daemon创建文件和目录时拥有必要的权限)

    5、修改进程当前工作目录(通常改为根目录 /,保证根目录的文件系统不会被卸载即可,如:cron会将自身放在/var/spool/cron 目录下)

    6、关闭daemon从父进程继承而来的所有打开着的文件描述符(由于daemon失去了控制终端,对0,1,2描述符完全可以关闭;无法卸载长时间运行的daemon打开的文件所在的文件系统----文件描述符是一种有限资源)

    7、关闭0,1,2文件描述符后,daemon通常会打开/dev/null,并让所有描述符都指向该设备

    --这样确保了当daemon调用在这些文件描述符上执行IO的库函数时不会出乎意料的失败;

实例:

import sys,os,time

def main():

    """ A demo daemon main routine, write a datestamp to /tmp/daemon-log every 10 seconds."""

    f = open("/tmp/daemon-log", "w") 

    while 1: 

        f.write('%s/n' % time.ctime(time.time())) 

        f.flush() 

        time.sleep(10) 

if __name__ == "__main__":

    # do the UNIX double-fork magic

    try: 

        pid = os.fork() 

        if pid > 0:

            # exit first parent

            sys.exit(0) 

    except OSError, e: 

        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 

        sys.exit(1)

    # decouple from parent environment

    os.chdir("/") 

    os.setsid() 

    os.umask(0) 

    # do second fork

    try: 

        pid = os.fork() 

        if pid > 0:

            # exit from second parent, print eventual PID before

            print "Daemon PID %d" % pid 

            sys.exit(0) 

    except OSError, e: 

        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 

        sys.exit(1) 

        

    # start the daemon main loop

    main()

©著作权归作者所有:来自51CTO博客作者位鹏飞的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消