如何在子进程中等待父进程退出?

5
我想分叉一个进程,在父进程退出之前等待,在子进程中做一些事情。

你尝试过什么?请参考帮助部分,了解如何正确地提问。 - ndugger
1
@ndugger 这是一个自问自答的问题,请参考答案中的“我尝试过什么”。 - Florian Margaine
@Arne 这只是一个玩笑。 - ndugger
1个回答

8
天真的方式是像这样使用忙循环:
# BAD WAY!
pid = os.fork()
if pid == 0:
    while True:
        if os.path.isdir("/proc/%s" % pid):
            break
        time.sleep(0.1)
    # Parent is dead there.

但是这种方法容易受到PID重用问题的影响。如果父进程退出后立即创建另一个进程并获得其PID,则子进程将永远不会退出。
另一种方法是在特定文件上使用flock()。但这不起作用,因为子进程与父进程共享相同的锁。
一个可靠的解决方法是使用一个特殊的技巧:在父进程中创建一个管道,在子进程中等待直到收到EOF信号。
# Good way
read_fd, write_fd = os.pipe()

pid = os.fork()
if pid > 0:
    # Close the read pipe, so that only the child is the reader.
    os.close(read_fd)

    # It is important to voluntarily leak write_fd there,
    # so that the kernel will close it for the parent process
    # when it will exit, triggering our trick.

elif pid == 0:
    # Daemon ourselves first.
    os.setsid()
    for fd in {0, 1, 2}:
        os.close(fd)

    # Close the write pipe so that the parent is the only writer.
    # This will make sure we then get an EOF when the only writer exits.
    os.close(write_fd)

    # Now, we're waiting on the read pipe for an EOF.
    # PS: the assert is not necessary in production...
    assert os.read(read_fd, 1) == ""
    os.close(read_fd)

    # At this point, the parent is dead.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接