C++ Signal Handling
A signal is an interrupt delivered to a process by the operating system, which can prematurely terminate a program. On UNIX, LINUX, Mac OS X, or Windows systems, an interrupt can be generated by pressing Ctrl+C.
Some signals cannot be caught by the program, but the signals listed below can be caught within a program and appropriate actions can be taken based on the signal. These signals are defined in the C++ header file <csignal>
.
Signal | Description |
---|---|
SIGABRT | Abnormal termination of the program, such as calling abort. |
SIGFPE | Erroneous arithmetic operation, such as division by zero or an operation resulting in overflow. |
SIGILL | Detection of an illegal instruction. |
SIGINT | Program interrupt signal. |
SIGSEGV | Illegal memory access. |
SIGTERM | Termination request sent to the program. |
signal() Function
The C++ signal handling library provides the signal function to catch unexpected events. Here is the syntax for the signal() function:
void (*signal (int sig, void (*func)(int)))(int);
This can be a bit difficult to understand, so the following syntax format is easier to grasp:
signal(registered signal, signal handler)
This function takes two parameters: the first is an integer representing the signal number; the second is a pointer to the signal handling function.
Let's write a simple C++ program that uses the signal() function to catch the SIGINT signal. Regardless of the signal you want to catch in your program, you must use the signal function to register the signal and associate it with the signal handler. See the following example:
Example
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// Clean up and close
// Terminate program
exit(signum);
}
int main ()
{
// Register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
Going to sleep....
Going to sleep....
Going to sleep....
Now, press Ctrl+C to interrupt the program, and you will see the program catch the signal, print the following content, and exit:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
raise() Function
You can generate a signal using the raise() function, which takes an integer signal number as a parameter. The syntax is as follows:
int raise (signal sig);
Here, sig is the number of the signal to be sent, which includes: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. Below is an example of generating a signal internally using the raise() function:
Example
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// Clean up and close
// Terminate program
exit(signum);
}
int main ()
{
int i = 0;
// Register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}
When the above code is compiled and executed, it will produce the following result and will exit automatically:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.