C++ Signal Handling

Signals are interrupts 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 a program, but the signals listed in the following table can be caught in 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 a program, such as a call toabort。
SIGFPE Erroneous arithmetic operations, such as division by zero or operations that cause overflow.
SIGILL Detect illegal instructions.
SIGINT Program termination (interrupt) signal.
SIGSEGV Illegal memory access.
SIGTERM A termination request sent to the program.

signal() function

The C++ signal handling library provides asignalA function used to capture unexpected events. Below is the syntax of the signal() function:

void (*signal (int sig, void (*func)(int)))(int); 

This looks a bit cumbersome. The following syntax format is easier to understand:

signal(registered signal, signal handler)

This function takes two parameters: the first parameter is the identifier of the signal to be set, and the second parameter is a pointer to the signal handling function. The function return value is a pointer to the previous signal handling function. If no signal handling function was set previously, the return value is SIG_DFL. If the previously set signal handling function was SIG_IGN, the return value is SIG_IGN.

Let's write a simple C++ program that uses the signal() function to catch the SIGINT signal. No matter what signal you want to catch in a program, you must usesignalfunction to register a signal and associate it with a signal handler. Consider 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 results:

Going to sleep....
Going to sleep....
Going to sleep....

Now, press Ctrl+C to interrupt the program. You will see the program catch the signal. The program prints the following content and exits:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

raise() function

You can use the functionraise()Generates a signal. This function takes an integer signal number as a parameter. The syntax is as follows:

int raise (signal sig);

Here,sigis the number of the signal to be sent. These signals include: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. The following 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 produces the following results and will exit automatically:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
other extensions