13 Signals in Linux

Lecture



The last lecture was on Linux processes. Today we will talk about the interaction of the process with each other, as well as how we can influence the processes. First, let's see how processes can interact with each other. We already wrote in the command line constructions like this: less / etc / group | grep user . In this example, the less process interacts with the grep process through a mechanism called the non- naming channel or pipe ( pipe ). We will not go into details, just remember that through the symbol | which in this case can be called “pipe” information (the result of the execution) of the process less goes to the input of another process - grep . Thus, one process passed information to another process.

  13 Signals in Linux

Another way of communicating processes is named pipes. The study of named channels is not included in this course, but on a practical example I will tell what it is. Named channel can be created com *** th mkfifo :

igor @ adm-ubuntu: ~ / linux $ mkfifo my_pipe
igor @ adm-ubuntu: ~ / linux $ ls -l | grep my_pipe
prw-r – r– 1 igor igor 0 2009-11-09 17:59 my_pipe

Now in one console, execute the following ***:

igor @ adm-ubuntu: ~ / linux $ echo Hello> my_pipe

As you can see someone *** and does not complete its work, but waits. Register another console and execute com *** at:

igor @ adm-ubuntu: ~ / linux $ cat my_pipe
Hello

If you return to the first console, you will see that *** and echo has completed its work. Thus, through the named channel my_pipe com *** a (process) echo transmitted information (the word Hello ) to the cat process, which received it and displayed it.

Let's now consider the main way to “communicate” processes - signals . One process using the kernel can transfer a special numeric signal value to another process. The process calls the signal transfer function and transmits the necessary information ( signal code, process PID ) to the kernel. The kernel transmits a signal to the process to the recipient and monitors how this signal is processed. Signals are denoted by numbers or mnemonic symbols. The list of signals can be outputted by the *** *** kill -l com.

The mnemonic names you see ( SIGTERM, SIGINT, SIGKILL ) begin with the prefix SIG . Names in this form are used in programming languages ​​such as C. The bash interpreter uses either numbers or mnemonic names, but without the prefix SIG - TERM, INT, KILL .

Part of the signals (INT, TERM) are intercepted. This means that the process when receiving such a signal should go to a special subroutine, which is engaged in signal processing. If there are no processing subroutines (the developers of a program that runs in the context of a process are involved in its writing), then control is transferred to the kernel, which performs the default actions described for each signal .

  13 Signals in Linux

Part of the signals are those that can be blocked. For example, one process sends a TERM signal to another process, and it in turn has not completed an I / O operation. In this case, the second process can block the received signal (again in the signal handler) until the execution of the necessary input / output operation. The TERM signal is a signal for the process to shut down correctly. The handler of this signal must perform all necessary actions to complete the work correctly.

And there is a third group of signals that are not blocked and for which no handlers are needed. An example of such a signal is the KILL signal . This signal destroys the process, since there are no handlers for it in the processes, it will be processed by the kernel by default, and since it is not blocked, actions will be executed immediately.

While we were talking about how processes “communicate” with each other using signals . But we (users) can also send signals to processes. For example, the key combination Ctrl + C sends a process signal INT , which interrupts the process. If you type in the terminal a com *** at sleep 100 , then the com *** will not return control to the terminal until it is completed. You can interrupt the execution of this command by pressing the key combination Ctrl + C.

What are the differences between similar signals INT, TERM, KILL (as well as QUIT and HUP )? Despite the similar differences there are:

The KILL signal is not blocked or intercepted and leads to the immediate completion of the process.
The INT signal , unlike KILL, is a blockable signal and intercepted.
The TERM signal is also intercepted and blocked and is intended for the correct (preferred) termination of the process.
The QUIT signal is similar to TERM , but allows you to save a memory dump.
The HUP signal - now this signal is most often interpreted by processes as “read configuration files”.

Consider two signals : STOP and CONT . The STOP signal stops the process, that is, the process goes into a “ stopped ” state. In such a state, the process will continue until it receives a signal again. If the CONT signal is received, the process will resume its operation from the moment it was stopped. Practical example:

Type in the terminal com *** at sleep 1000 & .

Then check that the process is in a standby state, as indicated by the letter S in the STAT column:

igor @ ubuntu: ~ $ ps x | grep [s] leep
PID TTY STAT TIME COMMAND
6301 pts / 1 S 0:00 sleep 1000

Now send the process a STOP signal . To do this, use the *** com at kill ( kill is the name of the process PID process ):

igor @ ubuntu: ~ $ kill -STOP 6301
[1] + Stopped sleep 1000

Check the status of the process:

igor @ ubuntu: ~ $ ps x | grep [s] leep
PID TTY STAT TIME COMMAND
6301 pts / 1 T 0:00 sleep 1000

We see that the process is indeed in the “stopped” state (the T symbol in the STAT column).

Now we will send a continuation signal (CONT) to the process and check the status:

igor @ ubuntu: ~ $ kill -CONT 6301
igor @ ubuntu: ~ $ ps x | grep [s] leep
PID TTY STAT TIME COMMAND
6301 pts / 1 S 0:00 sleep 1000

If you need to complete the process correctly, you need to send him a TERM signal :

igor @ ubuntu: ~ $ kill -TERM 6301
igor @ ubuntu: ~ $ ps x | grep [s] leep
[1] + Terminated sleep 1000
igor @ ubuntu: ~ $ ps x | grep [s] leep

If immediately after sending the TERM signal, perform a com *** at ps x | grep [s] leep , then you can have time to see the message that the process is terminating, in the next attempt to display information about our sleep process, we will not see anything - the process has ceased to exist. Com *** and kill without a signal, the default is the process process signal TERM . Therefore, it was possible to write just kill 6301 .

If it is necessary to urgently terminate the process, or the process does not terminate on the TERM signal, then the KILL signal should be sent to the process:

igor @ ubuntu: ~ $ sleep 1000 &
[1] 6348
igor @ ubuntu: ~ $ kill -KILL 6348
igor @ ubuntu: ~ $ ps x | grep [s] leep
[1] + Killed sleep 1000

If you need to send the same signal to several processes, then you can list them separated by a space: kill -TERM 2345 3456 4567 .

Com *** and kill is quite limited in its capabilities and does not allow performing more complex actions. Therefore, consider another com *** y - killall . The main advantage of this command is that it can send signals to all processes with the same name or all processes of the same user. Run the com *** *** sleep 1000 & several times in a row:

igor @ ubuntu: ~ $ ps x | grep [s] leep
6460 pts / 1 S 0:00 sleep 1000
6461 pts / 1 S 0:00 sleep 1000
6462 pts / 1 S 0:00 sleep 1000
6463 pts / 1 S 0:00 sleep 1000
6464 pts / 1 S 0:00 sleep 1000
6465 pts / 1 S 0:00 sleep 1000
6466 pts / 1 S 0:00 sleep 1000

Now, to complete all the processes with the name sleep , just dial the kill *** sleep com: ***

igor @ ubuntu: ~ $ killall sleep
[1] Terminated sleep 1000
[2] Terminated sleep 1000
[3] Terminated sleep 1000
[4] Terminated sleep 1000
[6] - Terminated sleep 1000
[7] + Terminated sleep 1000
[5] + Terminated sleep 1000

Run com *** at sleep 1000 & a few more times, and then log in to another console on behalf of another user (for example, test) and also execute com on *** on sleep 1000 & . Now go back to your console and view the sleep processes of all users:

igor @ ubuntu: ~ $ ps aux | grep [s] leep
igor 6540 0.0 0.0 2952 628 pts / 1 S 22:30 0:00 sleep 1000
igor 6541 0.0 0.0 2952 632 pts / 1 S 22:30 0:00 sleep 1000
igor 6542 0.0 0.0 2952 628 pts / 1 S 22:30 0:00 sleep 1000
test 6543 0.0 0.0 2952 632 pts / 3 S 22:30 0:00 sleep 1000
test 6544 0.0 0.0 2952 628 pts / 3 S 22:30 0:00 sleep 1000
test 6545 0.0 0.0 2952 628 pts / 3 S 22:30 0:00 sleep 1000
test 6546 0.0 0.0 2952 632 pts / 3 S 22:30 0:00 sleep 1000

Now, in order to remove the processes of the test user only, you need to run (on behalf of the root user ) com *** from killall -u test :

igor @ ubuntu: ~ $ sudo killall -u test
igor @ ubuntu: ~ $ ps aux | grep [s] leep
igor 6540 0.0 0.0 2952 628 pts / 1 S 22:30 0:00 sleep 1000
igor 6541 0.0 0.0 2952 632 pts / 1 S 22:30 0:00 sleep 1000
igor 6542 0.0 0.0 2952 628 pts / 1 S 22:30 0:00 sleep 1000

A com *** and above will remove not only sleep processes, but in general all user test processes. If it is necessary to delete the sleep processes specifically, then the *** one should have been written like this: killall -u test sleep .

If you run a com *** from killall with the -i switch, then before sending a signal, confirmation will be requested:

igor @ ubuntu: ~ $ killall -i sleep
To beat sleep (6540)? (y / n) n
To beat sleep (6541)? (y / n) n
To beat sleep (6542)? (y / n) n

The next lecture will be the final topic on Linux processes and signals. We'll talk about jobs, com *** ah jobs, fg, bg , strong> nohup, and top .


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

LINUX operating system

Terms: LINUX operating system