Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we use exit or return in child process

Tags:

c++

c

linux

fork

unix

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?

like image 548
Yves Avatar asked May 11 '19 12:05

Yves


People also ask

When would you use exit instead of return?

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.

How do you end a child process?

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.

What happens to child process if parent exits?

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.

Which system call we use to get the return status of a child process?

WEXITSTATUS(status) : returns the exit status of the child.


1 Answers

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.

like image 162
bk2204 Avatar answered Sep 19 '22 23:09

bk2204