Ways to Terminate or Kill Process

Discussion in 'C' started by poornaMoksha, Nov 8, 2011.

  1. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    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()
    2. Call exit() function
    3. Call _exit() or _Exit() function
    4. Return of last thread from its triggering function
    5. Calling pthread_exit() function from the last thread
    6. Calling abort() function
    7. When a signal is received
    8. Response of last thread to a cancellation request.

    Lets understand all these ways one by one :

    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 :

    Code:
    #include<stdio.h> 
      
     int func(void) 
     { 
         printf("\n Inside func()\n"); 
         return 0; 
     } 
      
     int main(void) 
     { 
         printf("\n Hello World\n"); 
         func(); 
         printf("\n returning from main()\n"); 
      
         return 0; 
     }
    The output of the above code is :

    Code:
    ~/practice $ ./helloWorld  
      
      Hello World 
      
      Inside func() 
      
      returning from main()
    We see that the function func() is executed and then the code flow returns to main() and then the rest of the main() function is executed.

    Now, lets see another example :

    Code:
    #include<stdio.h> 
     #include<stdlib.h> 
      
     void func(void) 
     { 
         printf("\n Inside func()\n"); 
         exit(0); 
     } 
      
     int main(void) 
     { 
         printf("\n Hello World\n"); 
         func(); 
         printf("\n returning from main()\n"); 
      
         return 0; 
     }
    The output of the above code comes out to be :

    Code:
    ~/practice $ ./helloWorld  
      
      Hello World 
      
      Inside func()
    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 :

    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 :

    Code:
    ~/practice $ ./small_signal  
     ^C 
     ~/practice
    So, looking at the output, we see that the process got terminated.

    Now, lets handle the signal generated by ctrl+c, here is the code :

    Code:
    #include<stdio.h> 
     #include<signal.h> 
     #include<unistd.h> 
      
     void sig_handler(int signo) 
     { 
        if (signo == SIGINT) 
            printf("received SIGUSR1\n"); 
        else 
            printf("ERR : received signal %d\n", signo); 
     } 
      
      
     int main(void) 
     { 
         if (signal(SIGINT, sig_handler) == SIG_ERR) 
             printf("\ncan't catch SIGUSR1\n"); 
         while(1)  // Simulate a dummy wait 
             sleep(1); 
      
         return 0; 
     }
    In the above code, I used signal handling (http://www.go4expert.com/showthread.php?t=26840) to handle the signal generated from ctrl+c. Lets see the output :

    Code:
    ~/practice $ ./small_signal  
     ^Creceived SIGUSR1 
     ^Creceived SIGUSR1 
     ^Creceived SIGUSR1 
     Killed
    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 :

    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...
     
  2. archanababu

    archanababu Banned

    Joined:
    Oct 27, 2011
    Messages:
    12
    Likes Received:
    0
    Trophy Points:
    0
    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!!
     
  3. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    You are always welcome buddy!!!!
     
  4. globlesearching

    globlesearching New Member

    Joined:
    Dec 7, 2011
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    Professional
    Location:
    St. Petersburg, Florida
    Information is very informative i like this post. And I share to my all facebook friends...Keep submit more...

    Thanks for...
     
  5. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    Thanks, I regularly post articles here. Keep yourself updated!!!!!!
     
  6. Scripting

    Scripting John Hoder

    Joined:
    Jun 29, 2010
    Messages:
    421
    Likes Received:
    57
    Trophy Points:
    0
    Occupation:
    School for life
    Location:
    /root
    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
     
  7. sura

    sura Banned

    Joined:
    Aug 4, 2011
    Messages:
    47
    Likes Received:
    1
    Trophy Points:
    0
    Location:
    India,Tamil Nadu.
    Nice and Informative . . . . .
    Thanks.
     
  8. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    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.
     
  9. Scripting

    Scripting John Hoder

    Joined:
    Jun 29, 2010
    Messages:
    421
    Likes Received:
    57
    Trophy Points:
    0
    Occupation:
    School for life
    Location:
    /root
    I'm not sure whether it's only for Windows, but maybe yes ... I didn't noticed that line, sorry, my bad. :)
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice