A running instance of a program executable is known as a Process. A process when run can do various things like open some files, read/write some data, create some threads/processes, register some functions as callback in various scenarios etc. According to the logic, after the completion of the desired work, the process terminates. In this article we will focus over how a process terminates.

The focus here will be processes whose code is written in C and are running on Linux platform.

Process Termination

Since this article revolves around Linux processes written in 'C' , so there are eight ways for a process to terminate :

1) Return from main()

Well, this is the most common way of exiting from a process. Usually we do a return from main() whenever we want our process to terminate. Following is a piece of code explaining this :

Code:

#include<stdio.h>

int main(void)
{
printf("\n Hello World\n");
return 0;
}

In the above piece of code we see that we return from main() after we are done with the printf() call.

2) Call exit(int status) function

This is another common way that you must have seen in various functions. The difference being that while in a function other than main(), through 'return' one can terminate the current function and return to the caller function while through exit() we can terminate the process. Being used from main() both return and exit() have same effect ie the process is terminated. Lets understand it through an example code :

So its clearly visible through the output that after the exit() function is executed, the process gets terminated and the rest of the caller function (main() function) is not executed.

Note : In this example, I have changed the signature of the function func() so as to avoid the warning from compiler as now we are not returning anything from function func().

3) Call _exit(int status) or _Exit(int status) function

To begin with, lets clear the difference between the two. The major difference being that _Exit are specified by ISO C, whereas _exit is specified by POSIX.1. Otherwise both the functions perform the same operation. From the man page of _exit/_Exit we have :

Quote:

The function _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process's parent is sent a SIGCHLD signal.

The value status is returned to the parent process as the process's exit status, and can be collected using one of the wait(2) family of calls.

The function _Exit() is equivalent to _exit(). The function _exit() does not call any functions registered with atexit

Things are pretty much clear up till this point but what does that last line in the above quote from man page signify. Well this signifies one of the major differences between exit() function (explained in point 2 above) and the _exit/_Exit functions.

Lets understand what does atexit() function do ?

Well, 'atexit(void (*function)(void))' function registers a function that is called when the process terminates. It could be a clean up function for all the memory allocations done or simply could be used for any other work. If more that one functions are registered using atexit() function, then they are called in order from the last registered function to the first registered function.

Lets understand this difference between exit() and _exit/_Exit functions using an example :

Code:

#include<stdio.h>
#include<stdlib.h>
//#include<unistd.h>

void exit_func1(void);
void exit_func2(void);

int main(void)
{
printf("\n Inside main() \n");

if(0 != atexit(exit_func1))
{
printf("\n atexit() failed\n");
}

if(0 != atexit(exit_func2))
{
printf("\n atexit() failed\n");
}

printf("\n exiting main() \n");

exit(0);

return 0;
}

void exit_func1(void)
{
printf("\n exit_func1() called \n");
}

void exit_func2(void)
{
printf("\n exit_func2() called \n");
}

we see that in the above program, to functions are registered through atexit() function and the process being terminated through a call to exit(0) in the main() function.

Lets see the output of this program :

Code:

~/practice $ ./exit

Inside main()

exiting main()

exit_func2() called

exit_func1() called

So, we see that after the last print statement from the main() function the registered function get called in the order as described above.

Now, lets use the _exit() function instead of exit() function and see what happens. Here is the code :

Code:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

void exit_func1(void);
void exit_func2(void);

int main(void)
{
printf("\n Inside main() \n");

if(0 != atexit(exit_func1))
{
printf("\n atexit() failed\n");
}

if(0 != atexit(exit_func2))
{
printf("\n atexit() failed\n");
}

printf("\n exiting main() \n");

_exit(0);

return 0;
}

void exit_func1(void)
{
printf("\n exit_func1() called \n");
}

void exit_func2(void)
{
printf("\n exit_func2() called \n");
}

Now, lets see the output :

Code:

~/practice $ ./exit

Inside main()

exiting main()

So, its clear now looking at the output that once we used _exit() function, the registered functions through atexit() are not called and the control is directly transfered to the caller of main() function.

4) Return of last thread from its triggering function

Well, the last thread in any program is the thread in which main() runs. So its very obvious that when this thread returns, the process will terminate.

5) Calling pthread_exit() function from the last thread

Again, continuing from the explanation of point 4 above, the last thread is the thread in which main() runs, so calling pthread_exit() from this thread will terminate the thread in which main() is running and hence the process will terminate.

6) Calling abort() function

This is a special function causes abnormal termination of the process. It does this by first unblocking the SIGABRT signal and then issues this signal to the process from which it is called. The process is terminated unless this signal is called and the signal handler does not return(this could be achieved using longjmp() function).

7) When a signal is received

Yes, when a signal is received by a process which is not handling this type of signal, the process terminates. Consider what happens when you press ctrl+c on a running process. This user activity generates a SIGINT signal to the process. If the process is not handling this type of signal, the process terminates. Lets look at an example to understand this :

Code:

#include<stdio.h>

int main(void)
{
while(1) // Simulate a dummy wait
sleep(1);

return 0;
}

The above code does nothing, it just waits infinitely, which gives us ample time so that we can issue ctrl+c. When I run the above program, and issue ctrl+c , this is what I get :

So, from the output above, I ran the program and tried ctrl+c multiple time but could not terminate the program as the program now is handling the signal generated by ctrl+c. So, finally I had to issue the 'killall -9 small_signal' command from some other terminal to terminate the program.

8) Response of last thread to a cancellation request.

Well, if somehow we cancel the last thread (as explained in above points, the last thread is the thread in which main() function runs) surely the process will terminate. This can be achieved using the pthread_cancel() function of the pthread library.

A point worth noting

So, now we have understood almost all the ways to terminate a process, but did you think over the 'status' variable used in return statement or exit(), _exit() and _Exit() functions. Why do we need to pass this status? What do we gain from it?

Well, it is used to provide the exit status of the process. This exit status would determine whether the process completed successfully or it failed.

On a command line, the exit status is fetched by command :

Quote:

echo $?

Lets take a small example to understand this :

Code:

#include<stdio.h>

int main(void)
{
printf("\n Hello World\n");

return 0;
}

When I run the following program and check the exit status, i see :

Code:

~/practice $ ./helloWorld

Hello World
~/practice $ echo $?
0

So the exit status is '0' which is same as what we returned in code.

Now lets change the return value and re confirm :

Code:

#include<stdio.h>

int main(void)
{
printf("\n Hello World\n");

return 2;
}

The output :

Code:

~/practice $ ./helloWorld

Hello World
~/practice $ echo $?
2

So we see that once we changed the return value to '2', the exit status also becomes '2'.

On a final note, the standard is that the return value '0' is used for success while any other value signifies failure.

Conclusion

To conclude, in this article, we studied different ways in which a program can terminate and how it behaves while termination.

Stay tuned for more...

archanababu

22Nov2011 14:29

Re: Ways to Terminate or Kill Process

By reading ur article i got really helpful information about kill or terminate a process. Also got information about process and what the process is. Thanks dear!!

poornaMoksha

23Nov2011 11:40

Re: Ways to Terminate or Kill Process

Quote:

Originally Posted by archanababu
(Post 89441)

By reading ur article i got really helpful information about kill or terminate a process. Also got information about process and what the process is. Thanks dear!!

You are always welcome buddy!!!!

globlesearching

7Dec2011 12:50

Re: Ways to Terminate or Kill Process

Information is very informative i like this post. And I share to my all facebook friends...Keep submit more...

Thanks for...

poornaMoksha

7Dec2011 14:02

Re: Ways to Terminate or Kill Process

Quote:

Originally Posted by globlesearching
(Post 89894)

Information is very informative i like this post. And I share to my all facebook friends...Keep submit more...

Thanks for...

Thanks, I regularly post articles here. Keep yourself updated!!!!!!

Scripting

14Dec2011 22:08

Re: Ways to Terminate or Kill Process

Nice tut man, good work done, but what about the way TerminateProcess(GetCurrentProcess(),0);

I know it's pretty brute-force way, but still a way :D

sura

18Dec2011 21:17

Re: Ways to Terminate or Kill Process

Nice and Informative . . . . .
Thanks.

poornaMoksha

21Dec2011 15:24

Re: Ways to Terminate or Kill Process

Quote:

Originally Posted by Scripting
(Post 90286)

Nice tut man, good work done, but what about the way TerminateProcess(GetCurrentProcess(),0);

I know it's pretty brute-force way, but still a way :D

I think that this function is for windows.
I already specified in my article: The focus here will be processes whose code is written in C and are running on Linux platform.

Scripting

23Dec2011 19:59

Re: Ways to Terminate or Kill Process

Quote:

Originally Posted by poornaMoksha
(Post 90442)

I think that this function is for windows.
I already specified in my article: The focus here will be processes whose code is written in C and are running on Linux platform.