python 守护进程daemon

复制代码
import time
import os
import sys
def close_std_fd():
    f = open(os.devnull, 'w')
    sys.stdin = f
    sys.stdout = f
    sys.stderr = f

def daemon(func):
    pid = os.fork()
    if pid > 0:
        return
    os.setsid()
    pid = os.fork()
    if pid > 0:
        return
    os.chdir('/')
    os.umask(0)
    close_std_fd()
    func()


def maketest():
        time.sleep(8888)

daemon(maketest)
复制代码

 

复制代码
# -*-coding:utf-8-*-
import sys, os

'''将当前进程fork为一个守护进程

    注意:如果你的守护进程是由inetd启动的,不要这样做!inetd完成了
    所有需要做的事情,包括重定向标准文件描述符,需要做的事情只有
    chdir() 和 umask()了
'''
def daemonize(stdin='/dev/null',stdout= '/dev/null', stderr= 'dev/null'):
    '''Fork当前进程为守护进程,重定向标准文件描述符
        (默认情况下定向到/dev/null)
    '''
    #Perform first fork.
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)  #first parent out
    except OSError, e:
        sys.stderr.write("fork #1 failed: (%d) %s\n" %(e.errno, e.strerror))
        sys.exit(1)

    #从母体环境脱离
    os.chdir("/")
    os.umask(0)
    os.setsid()
    #执行第二次fork
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0) #second parent out
    except OSError, e:
        sys.stderr.write("fork #2 failed: (%d) %s]n" %(e.errno,e.strerror))
        sys.exit(1)

    #进程已经是守护进程了,重定向标准文件描述符
    for f in sys.stdout, sys.stderr: f.flush()
    si = file(stdin, 'r')
    so = file(stdout,'a+')
    se = file(stderr,'a+',0)
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

def _example_main():
    '''示例函数:每秒打印一个数字和时间戳'''
    import time
    sys.stdout.write('Daemon started with pid %d\n' % os.getpid())
    sys.stdout.write('Daemon stdout output\n')
    sys.stderr.write('Daemon stderr output\n')

    c = 0
    while True:
        sys.stdout.write('%d: %s\n' %(c, time.ctime()))
        sys.stdout.flush()
        c = c+1
        time.sleep(1)

if __name__ == "__main__":
    daemonize('/dev/null','/home/del/daemon.log','home/del/daemon.log')
    _example_main()
复制代码

 

linux 中生成一个守护进程 为什么要 fork 两次。

All right, so now first of all: what is a zombie process?

It's a process that is dead, but its parent was busy doing some other work, hence it could not collect the child's exit status.

In some cases, the child runs for a very long time, the parent cannot wait for that long, and will continue with it's work (note that the parent doesn't die, but continues its remaining tasks but doesn't care about the child).

In this way, a zombie process is created.


Now let's get down to business. How does forking twice help here?

The important thing to note is that the grandchild does the work which the parent process wants its child to do.

Now the first time fork is called, the first child simply forks again and exits. This way, the parent doesn't have to wait for a long time to collect the child's exit status (since the child's only job is to create another child and exit). So, the first child doesn't become a zombie.

As for the grandchild, its parent has already died. Hence the grandchild will be adopted by the init process, which always collects the exit status of all its child processes. So, now the parent doesn't have to wait for very long, and no zombie process will be created.

 

posted on   思此狂  阅读(456)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示