?
Solved

How to clean up a C program when terminated??

Posted on 2004-04-29
9
Medium Priority
?
286 Views
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?

engin32us
0
Comment
Question by:engin32us
[X]
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
9 Comments
 
LVL 12

Expert Comment

by:stefan73
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.

Cheers,
Stefan
0
 
LVL 12

Assisted Solution

by:stefan73
stefan73 earned 450 total points
ID: 10956915
engin32us,

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);
      signal(sig,sighandler);
}

int main(){
      /* Setup signal handler */
      signal(SIGHUP,sighandler);
      signal(SIGINT,sighandler);
      signal(SIGTERM,sighandler);

      /* sleep() is interrupted by a signal, so we loop here */
      while(1) {
            sleep(999);
            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;

[...]
while(!shutdown){
    do_something();
}

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

Stefan
0
 
LVL 45

Expert Comment

by:sunnycoder
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)


cheers
sunnycoder
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
LVL 12

Expert Comment

by:stefan73
ID: 10958463
sunnycoder,
> use sigaction() interface instead of signal() interface

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

Stefan
0
 
LVL 4

Expert Comment

by:oumer
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 ......
0
 
LVL 4

Accepted Solution

by:
oumer earned 300 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

   if(!exited)
      exited=true;
   else
       return;

  //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;

atexit(bye);

//These three lines will mask the SIGINT from being catched by the child threads
sigemptyset(&set);
sigaddset(&set,SIGINT);
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);
sa.sa_handler=signal_handler;
sigemptyset(&sa.sa_mask);
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 ....

}
0
 
LVL 12

Expert Comment

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

Any ideas?

Stefan
0
 
LVL 4

Expert Comment

by:oumer
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 ..."
0
 
LVL 4

Expert Comment

by:oumer
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.
0

Featured Post

NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

Question has a verified solution.

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

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
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…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Suggested Courses

762 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