Signals in Linux is a very important concept to understand. This is because, signals are used in some of the common activities that you do through Linux command line. For example, whenever you press Ctrl+c to terminate an executing command from command line, you use signals. Whenever you use kill -9 [pid] to kill a process, you use signals. So, it is very useful to know at-least the basics of signals and that is exactly what we will discuss in this article.
What Is A Signal?
Signal is nothing but a way of communicating a message from one process to another. These messages are popularly known as notifications which the receiving process is free to process, ignore or leave it up to the OS to take default action (more on these options later). A notification sent by the sender process to the receiving process can be of various types. For example, a notification can be to kill the receiving process or let it know that it has accessed an invalid memory area or it can be a notification of availability of a resource (that was busy earlier) etc. So, you can see that signals are nothing but just another way of IPC (inter Process Communication).
Why Are Signals Important?
Signals are important, in-fact very important because they drive some of the most popular programming and system administration activities. For example, let's take example of a debugger. Most of the programmers use a debugger to debug their program code while it is executing. If you would have ever used a debugger, you would know that breakpoints are used to halt the execution of a program at specified lines of code.
Did you ever think what makes a program aware that a breakpoint has been hit and it needs to halt the execution? Yes, it is a signal (SIGSTOP) that is sent to the program in this case. And when the user is done with debugging, a signal (SIGCONT) is sent to the program -- after which the program continues the execution.
So, this was one example. But there are numerous other activities that are completely dependent on signals.
How A Program Handles Signals?
A program can handle signals in the following three ways :
- A program may provide its own signal handler for handling a particular signal -- This is especially important in those cases where a program has to perform some tasks (for example - memory clean-up activities) in response to the received signal. A signal handler is nothing but a function defined in the program code that gets executed automatically (actually it gets triggered by the OS kernel) when a signal is received by the program.
- A Program may do nothing on receipt of a signal -- Every signal has a default action associated with it. In a scenario where a program just don't care for a signal, the default action corresponding to that particular signal is taken by the OS kernel.
- A program may choose to ignore a signal -- In this situation, the signal (or set of signals) are blocked and are hence not delivered to to the program. A program may choose to ignore signals which -- the programmer thinks -- are irrelevant to it.
Different Types Of Signals
To get a list of signals supported on your Linux system, just issue the following command :
The -l option of the kill command is used to list the signal names. Here is the output of this command on my system :
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
So you can see that the output consists of all the signals supported by my system. To get an idea about some of the popular signals, read this tutorial.
If you are a system administrator or a power command line user, you would have definitely used the following command to kill a process :
kill -9 <pid>
Where pid is the identifier of the process that you want to kill.
Did you ever think what exactly -9 signifies? Well, it signifies a signal with numeric value 9. Yes, signals (as you can see in the output of kill -l above) have numeric values associated with them. To know which signal has numeric value of 9, use the following command :
$ kill -l 9
So you can see that numeric value 9 corresponds to SIGKILL. Similarly, if it required to translate a signal name to its numeric value, you can use the same command.
For example :
$ kill -l KILL
So you can see that this way, numeric value corresponding to a signal name can be fetched.
The SIGSTOP AND SIGKILL Signals
The signals SIGSTOP and SIGKILL deserve a special mention because of the fact that these signals cannot be handled by programs.
SIGSTOP - This signal is sent by a process in order to halt a program so that it can be debugged. Now, suppose if the programs were given the capability of handling this signal and a program accidentally chooses to ignore this signal, then that program cannot be debugged ever.
SIGKILL - This signal is sent by a process in order to terminate the receiving process immediately. This means that the termination is abnormal and not graceful. This signal is used in cases where a process hangs or is to be terminated immediately -- for example, this signal is used by OS kernel sometimes when the system is shut-down.
Characteristics Of Signals
Here are some of the important characteristics of Linux signals :
- If a process has multiple threads then a signal interrupts only a single thread and not the complete process -- This applies to Linux kernel version 2.6 and higher.
- A signal handler can also get interrupted by the receipt of another signal
- Besides standard set of signals. There can be user defined signals too.
- In terms of code, signal handling can be done by using functions like signal() and sigaction().
In the next part of this article, we will discuss in detail the implementation of signals in Linux through C programs.