Comments (10)
I decided to not require boost.asio for the usage of
booost.process, so the current design doesn't cut it. You can use
on_exitfor that, which uses
asioand
SIGCHLD` under the surface. Does that not cut it for you?
from process.
I didn't actually notice on_exit was there, sorry. Yes, it's what I need.
from process.
I actually have some questions...
In https://www.boost.org/doc/libs/1_68_0/doc/html/boost/process/group.html#idp44884880-bb "Wait for the process group to exit" means "wait for any process of the process group to exit" or "wait for all the processes of the process group to exit"? Whatever the case, maybe the docs could be modified to make it extra clear?
I would want to be notified when my child, and every descendant of my child, has exited. This is probably only doable in Linux if cgroups are used, so limiting a bit my request (even if it would be cool to use cgroups to support this): I would want to be notified when my child, and every descendant of my child still in the same process group, has exited. This is not really doable with boost.proccess currently, is it?
Does the behaviour of https://www.boost.org/doc/libs/1_68_0/doc/html/boost/process/on_exit.html depend on whether the child was created with a process group or not? There is a need for an "on_group_exit"?
from process.
- Yeah, it means all children of the group. Rephrasing might be nice.
- I am not sure that's generally possible, since deep nested child processes might be in another group or have a
SIGIGN
set. You can just get the descriptor of the group throughnative_handle
to use it for extensions - if that cuts it for cgroup. - I am not sure that's feasible, because there's no
SIGGRP
- how would you implement that?
from process.
Yeah, at least to start with I would not bother trying to handle children that have changed process group. Those get lost. But I don't think it matters whether SIGCHLD is SIG_IGN in the children themselves, you will still get a signal if your own SIGCHLD is not SIG_IGN. If some child in the hierarchy has SIGCHLD with SIG_IGN either:
- The grandchildren will clean up by themselves
- The child will die first, the grandchildren will become your children, and you will waitid() for them.
I guess "on_exit" currently works like this:
- Wait for SIGCHLD
- Waitid for the children that SIGCHLD has just signalled
"on_group_exit" or "on_exit when the child has been created with a group" could:
- Wait for SIGCHLD
- waitid() for the children that SIGCHLD has just signalled
- (async)Wait for SIGCHLD
- waitid() for the process group id using the WNOHANG option
- If
4
returns ECHILD it means all the children in the process group have exited,3
is cancel() and "on_group_exit"/"on_exit" is called
from process.
The second doesn't work, because you might lose information, since waitpid
might reap a child process from the table while another part of your code waits for it.
from process.
Not sure I follow you here. But probably what you refer to can be solved by using WNOWAIT, in addition to WNOHANG, in 4
?
http://man7.org/linux/man-pages/man2/waitpid.2.html
WNOWAIT Leave the child in a waitable state; a later wait call can be used to again retrieve the child status information.
from process.
Ok, so you have process with pid 12
in group 13
and you wait for both asynchronously. If SIGCHLD
gets triggered, the waiting for 12 gets it, calls waitpid(12, &status, WNOHANG)
to check if it got it. Then it does not forward the signal. Even if it does, the handler for group 13 gets called, checks with waitpid(-13, &status, WNOHANG)
but then gets nothing because the information already got handled by the first call. That goes both ways, so we lose information.
from process.
First, let me say I obviously said something silly with The child will die first, the grandchildren will become your children, and you will waitid() for them
. init/"pid 1" becomes the parent of the grandchildren, not you.
The good news is that it's not silly anymore since Linux 3.14, which has PR_SET_CHILD_SUBREAPER
. But I don't think you would be interested in something Linux specific, only available since 30 Mar 2014?
But this is what I was proposing:
Supposing I have created a process group, 13, containing processes 12 and 13. Let's suppose PID 13 exits first.
/*
* FIRST
*
* me ->
* -> PID 13 ->
* -> PID 12
*/
prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
asio::signal_set chldSig(ioc, SIGCHLD);
group myGroup;
void do_child_wait() {
chldSig.async_wait(on_child_wait);
}
void on_child_wait(const error_code& ec, int) {
// PID 13 has exited
siginfo_t info;
waitid(P_PGID, myGroup.native_handle(), &info, WEXITED);
// Add code here to store the returned status if it's the right/main child
/*
* NOW
*
* me ->
* -> PID 12
*/
int ret = waitid(P_PGID, myGroup.native_handle(), &info, WEXITED | WNOHANG | WNOWAIT); // Checks if there are more children, without blocking and without modifying anything
if(ret == -1)
if(errno != ECHILD) {
on_exit(error)
return;
}
// There are no more children after all
on_exit(status_code);
return;
}
// There are more children, so let's wait until on_child_wait gets called again by chldSig.async_wait()
do_child_wait();
}
I have also changed the "3
is cancel()" part from my explanation since I understood chldSig
is not going to lose signals between async_wait() calls.
from process.
1. Yeah, it means all children of the group. Rephrasing might be nice.
FWIW I was now ready to open a different issue about this, since I was testing with boost 1.68. But I see you have fixed it already for 1.69 in eea7375 and it uses a quite similar thing to what I have just mentioned.
But while eea7375 is the best that can be done in a standard way. Using PR_SET_CHILD_SUBREAPER
if available would also make boost::process::group::wait()
more deterministic. Without PR_SET_CHILD_SUBREAPER
, Wait for the process group to exit
in boost::process::group::wait()
certainly means all children of the group
, but not all the processes in the group
(some processes can become children of PID 1, not of you) which is what I guess most people will expect to mean.
from process.
Related Issues (20)
- [v2] vfork_launcher undefined behaviour HOT 1
- Is it possible to add support for string_view? HOT 2
- boost::system::error_code not included in pipe_in/pipe_out when BOOST_PROCESS_USE_STD_FS is defined
- Process V2: Example fails to build when using BOOST_ASIO_SEPARATE_COMPILATION HOT 2
- Setting the capacity of the underline pipe. Linux only HOT 4
- Missing dependency on scope_exit with CMake build
- bp::environment::native_handle() cannot be compiled on Linux HOT 1
- Including boost/process.hpp causes build failure on Windows HOT 8
- [v2] Using async_execute with bind_cancellation_slot HOT 7
- Is it a typo mistake for "tempalte" in environment.hpp ?
- clang-15 error: expected unqualified-id due to dirfd macro in macOS 14 SDK
- clang-10 warning: comparison of integers of different signs: 'typename iterator_traits<__wrap_iter<char *> >::difference_type' (aka 'long') and 'const std::size_t' (aka 'const unsigned long')
- [Linux] boost::process:: child ::wait_until is not thread-safe HOT 6
- Boost CMake testing procedure doesn't work for Process
- [v2][Linux] process_is_running() returns false with musl libc
- boost\process\pipe.hpp(132,5): warning C4297: 'boost::process::basic_pipebuf<char,std::char_traits<char>>::~basic_pipebuf': function assumed not to throw an exception but does
- pipe_out leaks pipe source fd when redirecting both stdout and stderr to same pipe
- Modular Boost C++ Libraries Request HOT 1
- `child::terminate()` result in ECHILD in `on_exit` since boost 1.78 including 1.84
- include process v2 header file cause compile failed in aix platfrom
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from process.