How to wait for parent process to exit in a child?












4















I want to fork a process and wait for the parent to exit before doing something in the child.










share|improve this question























  • What have you tried? Please refer to the help section on how to properly ask a question. 👌

    – ndugger
    Feb 9 '18 at 10:11






  • 1





    @ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

    – Florian Margaine
    Feb 9 '18 at 10:16











  • @Arne it was a joke 👺

    – ndugger
    Feb 9 '18 at 10:19
















4















I want to fork a process and wait for the parent to exit before doing something in the child.










share|improve this question























  • What have you tried? Please refer to the help section on how to properly ask a question. 👌

    – ndugger
    Feb 9 '18 at 10:11






  • 1





    @ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

    – Florian Margaine
    Feb 9 '18 at 10:16











  • @Arne it was a joke 👺

    – ndugger
    Feb 9 '18 at 10:19














4












4








4


0






I want to fork a process and wait for the parent to exit before doing something in the child.










share|improve this question














I want to fork a process and wait for the parent to exit before doing something in the child.







python linux fork






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 9 '18 at 10:01









Florian MargaineFlorian Margaine

43.6k1074107




43.6k1074107













  • What have you tried? Please refer to the help section on how to properly ask a question. 👌

    – ndugger
    Feb 9 '18 at 10:11






  • 1





    @ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

    – Florian Margaine
    Feb 9 '18 at 10:16











  • @Arne it was a joke 👺

    – ndugger
    Feb 9 '18 at 10:19



















  • What have you tried? Please refer to the help section on how to properly ask a question. 👌

    – ndugger
    Feb 9 '18 at 10:11






  • 1





    @ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

    – Florian Margaine
    Feb 9 '18 at 10:16











  • @Arne it was a joke 👺

    – ndugger
    Feb 9 '18 at 10:19

















What have you tried? Please refer to the help section on how to properly ask a question. 👌

– ndugger
Feb 9 '18 at 10:11





What have you tried? Please refer to the help section on how to properly ask a question. 👌

– ndugger
Feb 9 '18 at 10:11




1




1





@ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

– Florian Margaine
Feb 9 '18 at 10:16





@ndugger this is a self-answered question, so please refer to the answers for "what I have tried".

– Florian Margaine
Feb 9 '18 at 10:16













@Arne it was a joke 👺

– ndugger
Feb 9 '18 at 10:19





@Arne it was a joke 👺

– ndugger
Feb 9 '18 at 10:19












1 Answer
1






active

oldest

votes


















6














The naive way would be a busy loop like this:



# 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.


But this is vulnerable to PID reuse issues. If another process is created right after the parent exits and gets its PID, the child will never exit.



Another way would be to use a flock() on a specific file. But it's not going to work, because the child shares the same locks as the parent.



A foolproof way to do this is using a special trick: create a pipe in the parent, and in the child, you just wait until you get an 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.





share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48703231%2fhow-to-wait-for-parent-process-to-exit-in-a-child%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    The naive way would be a busy loop like this:



    # 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.


    But this is vulnerable to PID reuse issues. If another process is created right after the parent exits and gets its PID, the child will never exit.



    Another way would be to use a flock() on a specific file. But it's not going to work, because the child shares the same locks as the parent.



    A foolproof way to do this is using a special trick: create a pipe in the parent, and in the child, you just wait until you get an 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.





    share|improve this answer






























      6














      The naive way would be a busy loop like this:



      # 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.


      But this is vulnerable to PID reuse issues. If another process is created right after the parent exits and gets its PID, the child will never exit.



      Another way would be to use a flock() on a specific file. But it's not going to work, because the child shares the same locks as the parent.



      A foolproof way to do this is using a special trick: create a pipe in the parent, and in the child, you just wait until you get an 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.





      share|improve this answer




























        6












        6








        6







        The naive way would be a busy loop like this:



        # 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.


        But this is vulnerable to PID reuse issues. If another process is created right after the parent exits and gets its PID, the child will never exit.



        Another way would be to use a flock() on a specific file. But it's not going to work, because the child shares the same locks as the parent.



        A foolproof way to do this is using a special trick: create a pipe in the parent, and in the child, you just wait until you get an 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.





        share|improve this answer















        The naive way would be a busy loop like this:



        # 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.


        But this is vulnerable to PID reuse issues. If another process is created right after the parent exits and gets its PID, the child will never exit.



        Another way would be to use a flock() on a specific file. But it's not going to work, because the child shares the same locks as the parent.



        A foolproof way to do this is using a special trick: create a pipe in the parent, and in the child, you just wait until you get an 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.






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 26 '18 at 13:12

























        answered Feb 9 '18 at 10:01









        Florian MargaineFlorian Margaine

        43.6k1074107




        43.6k1074107
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48703231%2fhow-to-wait-for-parent-process-to-exit-in-a-child%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga