A second primitive interprocess communication technique involves the use of signals. As previously indicated, signals occur asynchronously (with no specified timing or sequencing). Signals, which can be sent by processes or by the kernel, serve as notification that an event has occurred. Signals are generated when the event first occurs and are considered to be delivered when the process takes action on the signal. The delivery of most signals can be blocked so the signal can be acted upon later. Blocked signals, and those sent to processes in a non-running state are commonly called pending signals.
The symbolic name for each signal can be found in several places. Usually, the manual pages for signal ( try man 7 signal ) or the header file will contain a list of each signal name. Signals, as described in Section 7 of the manual, are shown in Table 4.13. The definition of a signal (its symbolic name, the associated integer value, and the event signaled) has evolved over time. Signals defined by the POSIX 1 standard have the letter P in the Def column; those defined by SUS v2 (Single UNIX Specification, version 2) have a letter S. The letter O indicates signals not defined by either of these standards. Furthermore, keep in mind that some signals are architecture-dependent . To denote this if three numbers are listed in the Value column for a signal, the first number is the signal for alpha and sparc platforms; the middle number is for i386 and ppc platforms; while the last number is for mips platforms. A dash () indicates the signal is missing for the platform. A single value indicates all platforms use the same signal number. The default action associated with the signal is defined by one or more letters in the Action column of the table. The letter A indicates the recipient process will terminate; B, the process will ignore the signal; C, the process will terminate and produce a core file; and D, the process will stop (suspend) execution. Additionally, the letter E indicates the signal cannot be caught (trapped), and the letter F, that the signal cannot be ignored.
Table 4.13. Signal Definitions.
Symbolic Name |
Def |
Value |
Action |
Description |
---|---|---|---|---|
SIGABRT |
P |
6 |
C |
Abort signal from abort . |
SIGALRM |
P |
14 |
A |
Timer signal from alarm . |
SIGBUS |
S |
10,7,10 |
C |
Bus error (bad memory access). |
SIGCHLD |
P |
20,17,18 |
B |
Sent to parent when child is stopped or terminated . |
SIGCLD |
O |
-,-,18 |
B |
A synonym for SIGCHLD. |
SIGCONT |
P |
19,18,25 |
B |
Resume if process is stopped. |
SIGEMT |
O |
7,-,7 |
C |
Emulation trap. |
SIGFPE |
P |
8 |
C |
Floating-point exception. |
SIGHUP |
P |
1 |
A |
A hangup was detected on the controlling terminal or the controlling process has died. |
SIGILL |
P |
4 |
C |
Illegal instruction. |
SIGINFO |
O |
29,-,- |
A synonym for SIGPWR. |
|
SIGINT |
P |
2 |
A |
Interrupt from keyboard. |
SIGIO |
O |
23,29,22 |
A |
I/O now possible. |
SIGIOT |
O |
6 |
C |
IOT trapequivalent to SIGABRT. |
SIGKILL |
P |
9 |
A,E,F |
Kill signalforce process termination. |
SIGLOST |
O |
-,-,- |
A |
File lock lost. |
SIGPIPE |
P |
13 |
A |
Broken pipe; write to pipe with no readers. |
SIGPOLL |
S |
23 |
A |
A pollable event has occurredsynonymous with SIGIO (also 23). |
SIGPROF |
S |
27,27,29 |
A |
Profiling timer expired . |
SIGPWR |
O |
29,30,19 |
A |
Power supply failure. |
SIGQUIT |
P |
3 |
C |
Quit from keyboard. |
SIGSEGV |
P |
11 |
C |
Invalid memory reference (segmentation violation). |
SIGSTKFLT |
O |
-,16,- |
A |
Coprocessor stack error. |
SIGSTOP |
P |
17,19,23 |
D,E,F |
Stop processnot from tty. |
SIGSYS |
S |
12,-,12 |
C |
Bad argument to system call. |
SIGTERM |
P |
15 |
A |
Termination signal from kill . |
SIGTRAP |
S |
5 |
C |
Trace/breakpoint trap for debugging. |
SIGTSTP |
P |
18,20,24 |
D |
Stop typed at a tty. |
SIGTTIN |
P |
21,21,26 |
D |
Background process needs input. |
SIGTTOU |
P |
22,22,27 |
D |
Background process needs to output. |
SIGUNUSED |
O |
-,31,- |
A |
Unused signal (will be SIGSYS). |
SIGURG |
S |
16,23,21 |
B |
Urgent condition on I/O channel (socket). |
SIGUSR1 |
P |
30,10,16 |
A |
User -defined signal 1. |
SIGUSR2 |
P |
31,12,17 |
A |
User-defined signal 2. |
SIGVTALRM |
S |
26,26,28 |
A |
Virtual alarm clock. |
SIGWINCH |
O |
28,28,20 |
B |
Window resize signal. |
SIGXCPU |
S |
24,24,30 |
C |
CPU time limit exceeded. |
SIGXFSZ |
S |
25,25,31 |
C |
File size limit exceeded. |
Some additional caveats to consider include the following:
Note that all signals begin with the prefix SIG and end with a semimnemonic suffix. For the sake of portability when referencing signals, it is usually best to use their symbolic names rather than their assigned integer values. The defined constants SIGRTMIN and SIGRTMAX are also found in and allow the generation of additional real-time signals. Real-time signals, usually the values 32 to 63, can be queued. The queuing of signals ensures that when multiple signals are sent to a process, they will not be lost. At present, the Linux kernel does not make use of real-time signals.
For each signal, a process may take one of the following three actions:
A discussion of the implementation details for ignoring and catching signals are covered in Section 4.5.
Signals are generated in a number of ways:
$ kill [ -signal ] pid . . .
When issued, the kill command will send the specified signal to the indicated PID. The signal can be an integer value or one of the symbolic signal names with the SIG prefix removed. If no signal number is given, the default is SIGTERM (terminate). The PID(s) (multiple PIDs are separated with whitespace) are the IDs of the processes that will be sent the signal. If needed, the ps command can be used to obtain current PIDs for the user.
It is possible for the pid value to be less than 1 and/or for the signal value to be 0. In these cases, the kill command will carry out the same actions as specified for the kill system call described in the following section. As would be expected, the kill command is just a command-line interface to the kill system call.
Notice that the argument sequence for the kill system call is the reverse of that of the kill command. The value specified for the pid argument indicates which process or process group will be sent the signal. Table 4.15 summarizes how to specify a process or process group.
Table 4.14. Summary of the kill System Call.
Include File(s) |
|
Manual Section |
2 |
|
Summary |
int kill( pid_t pid, int sig ); |
|||
Return |
Success |
Failure |
Sets errno |
|
-1 |
Yes |
Table 4.15. Interpretation of pid values by the kill System Call.
pid |
Process(es) Receiving the Signal |
---|---|
>0 |
The process whose process ID is the same as pid |
All the processes in the same process group as the sender |
|
-1 |
Not superuser : All processes whose real ID is the same as the effective ID of the sender Superuser : All processes excluding special processes |
<-1 |
All the processes whose process group is absolute_value ( - pid ) |
The value for sig can be any of the symbolic signal names (or the equivalent integer value) found in the signal header file. If the value of sig is set to 0, the kill system call will perform an error check of the specified PID, but will not send the process a signal. Sending a signal of 0 to a PID and checking the return value of the kill system call is sometimes used as a way of determining if a given PID is present. This technique is not foolproof, as the process may terminate on its own immediately after the call to check on it has been made. Remember that UNIX will reuse PID values once the maximum PID has been assigned. The statement
kill(getpid(),sig);
can be used by a process to send itself the signal specified by sig . [5]
[5] ANSI C also defines a raise library function that can be used by a process to send itself a signal.
If the kill system call is successful, it returns a 0; otherwise, it returns a value of -1 and sets errno as indicated in Table 4.16. In Linux, for security reasons, it not possible to send a signal to process one init . Signals are passed to init via telinit .
Table 4.16. kill Error Messages.
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
1 |
EPERM |
Operation not permitted |
|
3 |
ESRCH |
No such process |
No such process or process group as pid . |
22 |
EINVAL |
Invalid argument |
Invalid signal number specified. |
The alarm system call sets a timer for the issuing process and generates a SIGALRM signal when the specified number of real-time seconds have passed.
Table 4.17. Summary of the alarm System Call.
Include File(s) |
Manual Section |
2 |
||
Summary |
unsigned int alarm(unsigned int seconds); |
|||
Return |
Success |
Failure |
Sets errno |
|
Amount of time remaining |
If the value passed to alarm is 0, the timer is reset. Processes generated by a fork have their alarm values set to 0, while processes created by an exec inherit the alarm with its remaining time. alarm calls cannot be stackedmultiple calls will reset the alarm value. A call to alarm returns the amount of time remaining on the alarm clock. A "sleep" type arrangement can be implemented for a process using alarm . However, mixing calls to alarm and sleep is not a good idea.
Program 4.3 demonstrates the use of an alarm system call.
Program 4.3 Setting an alarm .
File : p4.3.cxx #include #include #include #include + #include #include using namespace std; int main(int argc, char *argv[] ) { 10 int w, status; if ( argc < 4 ) { cerr << "Usage: " << *argv << " value_1 value_2 value_3 " << endl; return 1; + } for(int i=1; i <= 3; ++i) if ( fork( ) == 0 ) { int t = atoi(argv[i]); cout << "Child " << getpid( ) << " waiting to die in " 20 << t << " seconds." << endl; alarm( t ); pause( ); cout << getpid( ) << " is done." << endl; } + while (( w=wait(&status)) && w != -1) cout << "Wait on PID: " << dec << w << " returns status of " << setw(4) << setfill(48) << hex << setiosflags(ios::uppercase) << status << endl; return 0; 30 }
When the program is invoked, three integer values are passed to the program. The parent process generates three child processes using the command-line values to set the alarm in process. In line 22 the pause library function is called. This function causes the child process to wait for the receipt of a signal. In the example, this will be the receipt of the SIGALRM signal. When the signal is received, the child process takes the default action for the signal. The default for SIGALRM is for the process to exit and return the value of the signal to its waiting parent. The parent process waits for all of the child processes to finish. As each finishes, the parent displays the child PID and its return status information. It is important to note that the cout statement in line 23 is never executed, as the child process exits before reaching this statement. This can be verified by the output shown in Figure 4.7.
Figure 4.7 Setting an alarm in multiple child processes.
linux$ p4.3 3 1 5 Child 17243 waiting to die in 3 seconds. Child 17244 waiting to die in 1 seconds. Child 17245 waiting to die in 5 seconds. Wait on PID: 17244 returns status of 000E Wait on PID: 17243 returns status of 000E Wait on PID: 17245 returns status of 000E <-- 1
(1) The child processes end in the order specified by their alarm times. Each passes back the SIGALRM value (14 an E in hexadecimal).
A call to pause suspends a process ( causing it to sleep) until it receives a signal that has not been ignored (Table 4.18).
Table 4.18. Summary of the pause Library Function. [6]
Include File(s) |
Manual Section |
2 |
||
Summary |
int pause ( void ); |
|||
Return |
Success |
Failure |
Sets errno |
|
If the signal does not cause termination then 1 returned |
Does not return |
Yes |
[6] While in Section 2 of the manual, the manual page indicates this is a library function.
pause returns a -1 if the signal received while pausing does not cause process termination. The value in errno will be EINTR (4). If the received signal causes termination, pause will not return (which is to be expected!).
Programs and Processes
Processing Environment
Using Processes
Primitive Communications
Pipes
Message Queues
Semaphores
Shared Memory
Remote Procedure Calls
Sockets
Threads
Appendix A. Using Linux Manual Pages
Appendix B. UNIX Error Messages
Appendix C. RPC Syntax Diagrams
Appendix D. Profiling Programs