Saying that I have used fork
to create one child process. Here is an example:
pid_t pid=fork();
if (pid==0) /* child */
{
// do something
exit(0); // _exit, exit or return????
}
else /* parrent */
{
wait(nullptr);
return 0;
}
I've seen many examples of fork
. Some of them used _exit
to terminate the child process to avoid flush the I/O buffer, others used exit
to terminate the child process. But non of them used return
. As my understanding, _exit
and exit
won't call destructors automatically, so is it better to call return
instead of exit
in the child process? Or because all examples that I've ever seen are C, instead of C++, so they don't need to worry about destructors?
return is a statement that returns the control of the flow of execution to the function which is calling. Exit statement terminates the program at the point it is used.
For killing a child process after a given timeout, we can use the timeout command. It runs the command passed to it and kills it with the SIGTERM signal after the given timeout. In case we want to send a different signal like SIGINT to the process, we can use the –signal flag.
The child process is spawned in the background. The shell waits for a newline (or an EOF) then kills the child. When the parent dies--no matter what the reason--it will close its end of the pipe. The child shell will get an EOF from the read and proceed to kill the backgrounded child process.
WEXITSTATUS(status) : returns the exit status of the child.
You can use either _exit
or exit
, but you shouldn't use return
. When you fork a child, you retain the entire call stack as part of forking the child. So if you use return
, you end up returning up all the way through your program, potentially continuing on and performing other tasks, which is almost certainly not what you want.
For example, if you have something like this snippet:
int get_value()
{
pid_t pid;
if (!(pid = fork())) {
int x = 0;
// do something with x.
exit(x);
}
else {
int status;
wait(&status);
return status;
}
}
int main()
{
int value = get_value();
switch (get_value()) {
case 0:
// call f
break;
case 255 << 8:
// call g
break;
}
}
you'll could end up calling f
or g
or doing other work with return
, which is definitely not desired.
If you call _exit
, functions that are registered with atexit
are not called. This is the right thing to do in threaded environments. If you're not working in a threaded environment and you don't have any handlers registered with atexit
, then they should be functionally equivalents.
If you want destructors in your child process to be called, put the child process code in its own function and let its variables be automatically destroyed when they go out of scope. exit
will not destroy objects for you, which is good because usually you do not want to destroy objects created in the parent process in your child process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With