python daemon-为什么这个函数杀死父母两次?

时间:2018-06-26 09:48:04

标签: python linux unix daemon

def daemon_start(pid_file, log_file):

    def handle_exit(signum, _):
        if signum == signal.SIGTERM:
            sys.exit(0)
        sys.exit(1)

    signal.signal(signal.SIGINT, handle_exit)
    signal.signal(signal.SIGTERM, handle_exit)

    # fork only once because we are sure parent will exit
    pid = os.fork()
    assert pid != -1

    if pid > 0:
        # parent waits for its child
        time.sleep(5)
        sys.exit(0)

    # child signals its parent to exit
    ppid = os.getppid()
    pid = os.getpid()
    if write_pid_file(pid_file, pid) != 0:
        os.kill(ppid, signal.SIGINT)
        sys.exit(1)

    os.setsid()
    signal.signal(signal.SIGHUP, signal.SIG_IGN)

    print('started')

    os.kill(ppid, signal.SIGTERM)

    sys.stdin.close()
    try:
        freopen(log_file, 'a', sys.stdout)
        freopen(log_file, 'a', sys.stderr)
    except IOError as e:
        shell.print_exception(e)
        sys.exit(1)

此守护程序不使用双叉。它说“只分叉一次,因为我们确定父母会退出”。父级调用sys.exit(0)退出。而子级调用os.kill(ppid,signal.SIGTERM)退出父级。

这样做意味着什么?

1 个答案:

答案 0 :(得分:0)

短语“ double fork”是一种标准技术,可确保将守护程序重新绑定到init(pid 1)进程,以使启动它的shell不会杀死它。这实际上是在使用该技术,因为第一个派生是由启动python程序的进程完成的。当程序调用{​​{1}}时,它将派生。原始(现在是父级)进程会在它派生的子级发出信号时几秒钟或更短的时间内退出。这将导致内核将子进程重新设置为pid1。“双叉”并不意味着守护程序两次调用daemon_start

此外,您的主题行询问“为什么此功能两次杀死父级?”但是有问题的代码没有做到这一点。我不知道你是怎么想到的。