How to clean up a C program when terminated??

Posted on 2004-04-29
Last Modified: 2010-04-22
Hi there...

I am writing a C program on linux which I want to terminate gracefully. That is, I want to be able to close all running threads that may be active at the time the user does Ctrl C. My program listens for socket conenctions and create serperate threads to handle the connections it receives and do some processing while the main thread continues to listen for connections. How do I terminate all the threads, close all sockets..etc when the user ends the program either by closing the console or by pressing Ctrl C or Z?

Question by:engin32us
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
LVL 12

Expert Comment

ID: 10956889
Hi engin32us,
Actually, you don't need to. All open files and sockets are closed when a process terminates. But yes, it is a good practice.

For your graceful termination you need signal handling. A CTRL-C is a SIGINT, and closing a terminal sends a SIGHUP to your process.

Check man signal and man 6 signal for details. I'll give you a simple example.

LVL 12

Assisted Solution

stefan73 earned 150 total points
ID: 10956915

Here you go:

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

static void sighandler(int sig){
      printf("Caught signal %d, resetting signal handler\n",sig);

int main(){
      /* Setup signal handler */

      /* sleep() is interrupted by a signal, so we loop here */
      while(1) {
            printf("Sleep woke up.\n");


(you'll need to kill it with -9, as it's also capturing SIGTERM)

For a more complex application with multiple threads, it's usually best not to close them instantly, but to use a shutdown flag which is monitored regularly:

int shutdown=0;


...your signal handler will set shutdown, so all threads shut down gracefully.

LVL 45

Expert Comment

ID: 10957351
Hi engin32us,

The approach is the same as what stefan recommended ... catch the signal ...

However, I highly recommend that you use sigaction() interface instead of signal() interface ... Sigaction is lot more powerful, flexible and less error prone as compared to singal()

man sigaction

>How do I terminate all the threads, close all sockets..etc
to kill the threads use pthread_kill ()

man pthread_kill

You will have all the socket ids in the main thread (it accepts the connections) ... You need to maintain a list of them (the active/open sockets) and during cleanup you can traverse that list and close all the open sockets ...

Alternatively you can register all the cleanup activity using the atexit() function

man atexit

The functions registered using atexit() will be called when the process is about to exit so you save the signal handling efforts ... However signal handling is more graceful and offers you better control

If you need more information, post back :o)

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 12

Expert Comment

ID: 10958463
> use sigaction() interface instead of signal() interface

Good point. I guess I was too lazy for using sigaction() :-)


Expert Comment

ID: 10959753
I have had several problems when using signals and threads. The best way I found is to just exit with the signal handler and do my cleanup with some function that I had registed at the beginning of my code. Also, I will mask the signal from all the threads except the one that I want to catch the signal, cause sometimes that also causes a problem. Example program will follow in a momment ......

Accepted Solution

oumer earned 100 total points
ID: 10959922
The skeleton code of how I would do is like this ....

bool exited = false;

void bye()
//I use the exited variable, cause I have sometimes encounterd bye being called more than once incase I press ctrl+c again while we are in bye


  //do you cleanup of threads and objects here


void signal_handler( int sig)
   printf("hmm, you don't like me anymore?\n");
   exit(0);  //atexit will be called at this point

void * thread_1(void *arg)
//thread_1's body


void * thread_2(void *arg)
//thread_1's body


int main()
sigset_t set;
struct sigaction sa;


//These three lines will mask the SIGINT from being catched by the child threads
pthread_sigmask(SIG_BLOCK, &set, NULL);

pthread_create(&th1, NULL, thread_1, NULL);
pthread_create(&th2, NULL, thread_2, NULL);

//now the threads are created, you can unmask the SIGINT now, making sure only the parent thread wil catch the signal
pthread_sigmask(SIG_BLOCK, &set, NULL);
sigaction(SIGINT, &sa, NULL);

//here you can wait for the two threads to finsih or do whatever you want to do
//just make sure you do something so that control doesn't reach to the end of the main function ....

LVL 12

Expert Comment

ID: 10976907
I wonder how Linux does the signal handling within a multi-threaded process when each thread has his own pid...

Any ideas?


Expert Comment

ID: 10977046
Hi Stefan,
>I wonder how Linux does the signal handling within a multi-threaded process when each thread has his own pid...
I dont get it when you say "when each thread has his own pid ..."

Expert Comment

ID: 10977141
Let's say you have a signal handler for some signals like SIG_FPE, SIG_SEGV, and SIG_INT

In the case of floating point ad segmentaion errors, the signals are sent to the concerned thread, the one that has caused the exception to happen. So if the signal handler was shared between the threads (i.e. you didn't mask the signals), it will be called from the concerned thread.

On the case asynchronous signals like sig_int when you press ctrl+c, there is no guarantee from which thread the signal handler will be called.

Featured Post

Tutorials alone can't teach real engineering

So we built better training tools.

-Hands-on Labs
-Instructor Mentoring
-Scenario-Based Tests
-Dedicated Cloud Servers

All at your fingertips. What are you waiting for?

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question