How to wait for parent process to exit in a child?
I want to fork a process and wait for the parent to exit before doing something in the child.
python linux fork
add a comment |
I want to fork a process and wait for the parent to exit before doing something in the child.
python linux fork
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
add a comment |
I want to fork a process and wait for the parent to exit before doing something in the child.
python linux fork
I want to fork a process and wait for the parent to exit before doing something in the child.
python linux fork
python linux fork
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
edited Nov 26 '18 at 13:12
answered Feb 9 '18 at 10:01
Florian MargaineFlorian Margaine
43.6k1074107
43.6k1074107
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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