Reputation: 193
I am confused about the ending of a process in UNIX. When is a process in UNIX terminated? Should we necessarily write exit(0)
to terminate a process? In my view- no, but I cannot figure out the difference between those two pieces of code.
pid_t pid=fork();
if(pid < 0)
{
perror("Fork error\n");
return 1;
}
else if (pid==0) /* child */
{
//Do some operations here
}
else
{
wait(NULL);
//Do some operations
}
and
pid_t pid=fork();
if(pid < 0)
{
perror("Fork error\n");
return 1;
}
else if (pid==0) /* child */
{
//Do some operations here
exit(0);
}
else
{
wait(NULL);
//Do some operations here
}
Probably we need the exit(0)
only for the wait()
function. In this case, what would happen if we make wait()
without having done exit(0)
before?
Upvotes: 1
Views: 955
Reputation: 4893
See exit()
:
Terminating a Process
It is important that the consequences of process termination as described occur regardless of whether the process called
_exit()
(perhaps indirectly throughexit()
) or instead was terminated due to a signal or for some other reason.
[...]
As required by the ISO C standard, using return from
main()
has the same behavior (other than with respect to language scope issues) as callingexit()
with the returned value. Reaching the end of themain()
function has the same behavior as callingexit(0)
.
See also wait()
. Normal termination:
If
wait()
orwaitpid()
return because the status of a child process is available, these functions shall return a value equal to the process ID of the child process.[...]
The value stored at the location pointed to bystat_loc
shall be0
if and only if the status returned is from a terminated child process that terminated by one of the following means:
- The process returned
0
frommain()
.- The process called
_exit()
orexit()
with a status argument of0
.- The process was terminated because the last thread in the process terminated.
List of specified termination reasons:
WIFEXITED(stat_val)
Evaluates to a non-zero value if status was returned for a child process that terminated normally.
WIFSIGNALED(stat_val)
Evaluates to a non-zero value if status was returned for a child process that terminated due to the receipt of a signal that was not caught (see
<signal.h>
).
and respective status information:
WEXITSTATUS(stat_val)
If the value of
WIFEXITED(stat_val)
is non-zero, this macro evaluates to the low-order 8 bits of the status argument that the child process passed to_exit()
orexit()
, or the value the child process returned frommain()
.
WTERMSIG(stat_val)
If the value of
WIFSIGNALED(stat_val)
is non-zero, this macro evaluates to the number of the signal that caused the termination of the child process.
To sum up, POSIX mentions two ways how a process can be terminated:
exit()
, _exit()
or returns from main()
or last thread of the process terminates;See also "Is it OK to call pthread_exit from main?" if you need to prevent all threads to terminate when main()
returns.
exit()
in childIn this case, what would happen if we make
wait()
without having doneexit(0)
before?
fork()
duplicates current process and both parent and child continue execution from the same point when fork()
returns.
Consider the following example:
int main() {
if (fork() == 0) { /* child */
foo();
}
else { /* parent */
wait(NULL);
}
bar(); /* called in parent in child */
return 0; /* or exit(0) */
}
In this example, child does not call exit()
in its if
branch, so after calling foo()
it calls bar()
and than returns from main()
causing child process termination. In other words, both child and parent call bar()
here.
Usually it's not what you want and you write this instead:
int main() {
if (fork() == 0) { /* child */
foo();
exit(0);
}
else { /* parent */
wait(NULL);
}
bar(); /* called only in parent */
return 0;
}
In this case, child exits immediately after calling foo()
so that bar()
in not called in child.
Upvotes: 2