More About Signals

Table of contents:

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:

  • For some S signals (SUS v2), the default action is listed as A (terminate) but by their actual action should be C (terminate the process and generate a core file).
  • Signal 29 is SIGINFO/SIGPWR on an alpha platform but SIGLOST on a sparc platform.

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:

  1. Perform the default action. This is the action that will be taken unless otherwise specified. The default action for each signal is listed in the previous table. Specifically these actions are

    • Terminate (Abort) Perform all the activities associated with the exit system call.
    • Core (Dump) Produce a core image (file) and then perform termination activities.
    • Stop Suspend processing.
    • Ignore Disregard the signal.
  2. Ignore the signal. If the signal to be ignored is currently blocked, it is discarded. The SIGKILL and SIGSTOP signals cannot be ignored.
  3. Catch the signal. In this case, the process supplies the address of a function (often called a signal catcher ) that is to be executed when the signal is received. In most circumstances, the signal catching function will have a single integer parameter. The parameter value, which is assigned by the system, will be the numeric value of the signal caught. When the signal catcher function finishes, the interrupted process will, unless otherwise specified, resume its execution where it left off.

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:

  1. By the kernel, indicating

    • Hardware conditions, the most common of which are SIGSEGV, when there has been an addressing violation by the process, and SIGFPE, indicating a division by zero.
    • Software conditions, such as SIGIO, indicating I/O is possible on a file descriptor or the expiration of a timer.
  2. By the user at a terminal:

    • Keyboard The user produces keyboard sequences that will interrupt or terminate the currently executing process. For example, the interrupt signal, SIGINT, is usually mapped to the key sequence CTRL+C and the terminate signal, SIGQUIT, to the key sequence CTRL+. The command stty -a will display the current mappings of keystrokes for the interrupt and quit signals.
    • kill command By using the kill command, the user, at the command line, can generate any of the previously listed signals for any process that has the same effective ID. The syntax for the kill command is

      $ 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.

  3. By other processes:

    • By the kill system call (Table 4.14). The kill system call is used to send a signal to a process or a group of processes.

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

  • Calling process does not have permission to send signal to specified process(es).
  • Process is not superuser and its effective ID does not match real or saved user ID.

3

ESRCH

No such process

No such process or process group as pid .

22

EINVAL

Invalid argument

Invalid signal number specified.

EXERCISE

The kill command also accepts the option -l (the letter L in lowercase), which lists the defined signals that kill knows about. At the system level, issue the command

$ kill -l

Find the (a) integer value, (b) default action, and (c) the event signaled for at least two signals that are known by the kill command but were not described in the previous signal table (Table 4.13).

EXERCISE

Write a parent program that fork s several child processes that each sleep a random number of seconds. The parent process should then wait for the child processes to terminate. Once a child process has terminated, the parent process should terminate the remaining children by issuing a SIGTERM signal to each. Be sure to verify (via the wait system call) that each child process terminated received the SIGTERM signal.

  • By the alarm system call (Table 4.17).

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



Interprocess Communication in Linux
Interprocess Communications in Linux: The Nooks and Crannies
ISBN: 0130460427
EAN: 2147483647
Year: 2001
Pages: 136

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net