
Signal Handling and Multithreading
Signals are the interrupts that are delivered to a process by the OS(Operating System) to terminate a program prematurely and attend the task for which the interrupt has been granted. Interrupts can also be generated by pressing Ctrl+C.
There are signals that cannot be caught by the program but there is a list of signals which can catch in the program and appropriate actions can be taken based on the signal.
Signals | Description |
---|---|
SIGABRT | (Signal Abort) Abnormal termination of the program, such as a call to abort. |
SIGFPE | (Signal floating- point exception) An erroneous arithmetic operation, such as a divide by zero or an operation resulting in overflow. |
SIGILL | (Signal Illegal Instruction) It is used for detecting an illegal instruction. |
SIGINT | (Signal Interrupt) It is used to receipt an interactive program interrupt signal. |
SIGSEGV | (Signal segmentation Violation) An invalid access to storage. |
SIGTERM | (Signal Termination) A termination request sent to the program. |
SIGHUP | (Signal Hang up) Hang Up (POSIX), its report that user’s terminal is disconnected. It is used to report the termination of the controlling process. |
SIGQUIT | Used to terminate a process and generate a core dump. |
SIGTRAP | Trace trap. |
SIGBUS | This is a BUS error which indicates an access to an invalid address. |
SIGUSR1 | User defined signal 1. |
SIGUSR2 | User defined signal 2. |
SIGALRM | Alarm clock, which indicates an access to an invalid address. |
SIGTERM | Used for termination. This signal can be blocked, handled, and ignored. Generated by kill command. |
SIGCOUNT | This signal sent to process to make it continue. |
SIGSTOP | Stop, unblockable. This signal is used to stop a process. This signal cannot be handled, ignored or blocked. |
The signal() Function
This signal() function is administered by the signal library and is used to catch unexpected interrupts or events.
Syntax of the signal() function:
void (*signal (int sig, void (*func)(int)))(int);
The signal function receives two arguments: the first argument is an integer that denotes signal number and the second argument is a pointer to the signal-handling function.
The raise() Function
The C++ language signal raise() function is used to send signals to the currently executing program. The raise function calls the signal handler. If no user-defined function is fixed for signal handling, it is implementation-defined whether the signal will be overlooked or the default handler will be invoked. It is defined in the header file of <csignal>.
The syntax for Signal Function:
int raise (int sig);
raise() Parameters
- SIGINT
- SIGABRT
- SIGFPE
- SIGILL
- SIGSEGV
- SIGTERM
- SIGHUP
Return value
Successful execution returns a 0 value and unsuccessful returns a non-zero value.
Example:
#include <iostream>
#include <csignal>
using namespace std;
sig_atomic_t siga_value = 0;
void handler(int sig)
{
siga_value = sig;
}
int main()
{
signal(SIGABRT, handler);
cout << "Before handler called" << endl;
cout << "Signal Value = " << siga_value << endl;
raise(SIGABRT);
cout << "After handler called" << endl;
cout << "Signal Value = " << siga_value << endl;
return 0;
}
OUTPUT
------
Before handler called
Signal Value = 0
After handler called
Signal Value = 6
Exceptions
This function will never throw an exception if no function handlers have been set with a signal to handle the raised signal.
Multithreading
Multithreading is a specific form of multitasking and multitasking is the characteristic that allows your computer to run two or more programs simultaneously. Multitasking is of two types: process-based and thread-based.
Process-based multitasking manages the parallel execution of programs. Thread-based multitasking deals with the parallel execution of pieces of the same program.
A multithreaded program includes two or more parts that can run parallelly. Every part of that program has described as a thread, and each thread of that program represents a separate path of execution.
Syntax:
#include<thread>
std::thread thread_object(callable)
C++ does not include any built-in support for multithreaded applications. Instead, it relies completely upon the OS(operating system) to implement this feature.
std::thread is the thread class that renders a single thread in C++ Programming Language. To begin a thread we simply need to generate a new thread object and pass the executing code to a callable object into the constructor of the object. Once the object is created a new thread is originated which will execute the code specified in callable.
Creating Threads
A thread can be created by:
- Using a function pointer
- Using a functor
- Using a lambda function
Points to Remember
std::thread
creates a new thread.- Threads created by
std::thread
do not have return values. - Each thread starts as soon as it gets created.
- We use
join()
function to wait for a thread to finish
Example
This simple example code creates 5 threads with the pthread_create() routine. Each thread prints a “Hello World!” message, and then terminates with a call to pthread_exit().
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#define NUMofTHREADS 5
using namespace std;
void *Hello(void *threadid)
{
long id;
tid = (long)threadid;
cout << "Hello World! Thread ID, " << id << endl;
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[NUMofTHREADS];
int a;
int x;
for( x = 0; x < NUMofTHREADS; x++ )
{
cout << "main() : creating thread, " << x << endl;
a = pthread_create(&threads[x], NULL, Hello, (void *)x);
if (a)
{
cout << "Error:unable to create thread," << a << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
Compile the program with -lpthread library as follows:
$gcc test.cpp -lpthread
Now, execute your program which gives the following output −
main() : creating thread, 0 main() : creating thread, 1 main() : creating thread, 2 main() : creating thread, 3 main() : creating thread, 4 Hello World! Thread ID, 0 Hello World! Thread ID, 1 Hello World! Thread ID, 2 Hello World! Thread ID, 3 Hello World! Thread ID, 4