Linux - process signal (on)

Table of contents

Preamble

1. What is a process signal

Second, the generation of the signal

2.1 Generate signal through key terminal

 2.2 Call the system function to signal the process

2.3 Signals generated by soft conditions

2.4 Signal generated by hardware exception

 Summarize


Preamble

The above mainly talked about the relevant knowledge of pipeline communication between processes. This article mainly leads you to have a deep understanding of the relevant knowledge of process signals. We mainly explain signal generation, signal storage, and signal processing from three aspects .

1. What is a process signal

Signals are not uncommon in our daily life, such as traffic lights, when we see a red light, we will know that we need to stop and will stop; when the alarm clock rings, we will get up; When we go downstairs, we'll go down to pick up deliveries and so on. These are typical signals, so we can get the first conclusion that signals are actually information plus processing actions.

 

And in these signals, we also found a feature, that is, even if we have not received the signal, we all understand the meaning of these signals, that is, we know how to deal with the signal. For example, even if the traffic light is not on, we also know that the red light needs to stop. Come down and wait. The same is true in the process. In reality, teachers or parents teach us how to handle signals, and in the process, our programmers teach our process how to handle signals.

In addition, in our daily life, signals may be generated at any time, such as courier delivery, we do not know the specific delivery time of the courier delivery, if the courier delivery is delivered, we are playing LOL passionate ranking, and we will immediately push the other party away Yes, at this time we may ask the courier to wait for two minutes below, and we will go down to pick it up after typing. At this time , signal generation——signal storage——signal processing is formed . There is an additional signal storage between the original signal generation and signal processing. Even if we cannot process this signal immediately, we need to save it. Leave it for later. Therefore, the generation of the signal is asynchronous to the process, that is, the process does not know when the signal is delivered, so it is busy with its own business before receiving the signal, and will not wait for the signal to be delivered without doing anything. .

 So how is the signal saved in the process? Where is it recorded?

First, let's take a look at the common signals in linux

 As shown in the figure above, each signal is composed of a number and a macro definition name, bounded by the red line, the first 31 signals are regular signals, which is the focus of our study in this lesson , and the latter are real-time signals that we are not currently studying .

Therefore, the signals we need to save are the first 31, so what can we do? Here we only need to confirm whether the signal is received, that is, whether the signal is present or not, so we can use 0 to indicate no, 1 to indicate yes, and there are exactly 31 signals, so we can use the data structure of the bitmap to represent, that is Map a signal with each binary bit of a 32-bit integer, such as the first bit mapping signal 1

 

 So where is this data stored?

In Linux, for each process, the operating system will create a task_struct structure to save its related information, so the above signal is stored in the task_struct corresponding to the process

struct task_struct
{
    ...
    uint_32 signal;
    ...
};

 Therefore, we can know that the so-called signaling is actually writing a signal, directly modifying the bits mapped in the signal bitmap of the process , and the task_struct structure is directly maintained by the operating system and can only be modified by the operating system, so no matter what the signal is later Generated, and finally the operating system completes sending

After talking about signal preservation, let's get to know signal processing a little bit. Signal processing mainly has the following three methods

1. Default actions, such as stop at red light and go at green light

2. Ignore the signal, such as you don't stop when the red light is on, keep walking

3. User-defined actions, such as when others stop at a red light, you are more awesome, you just come to a street dance

At this point, the basic understanding of the signal is over. Next, we will mainly talk about the generation of the signal.

Second, the generation of the signal

2.1 Generate signal through key terminal

What is a key terminal? In fact, it is to use the keyboard to input signals, such as the common Ctrl+c, Ctrl+\

 

As shown in the figure above, the user presses Ctrl-C, and this keyboard input generates a hardware interrupt, which is acquired by the OS, interpreted as a signal, and sent to the target foreground process. The foreground process receives the signal and causes the process to exit (mainly only the foreground process to receive the signal)

And Ctrl+c, Ctrl+\ correspond to signal 2 SIGINT and signal 3 SIGQUIT respectively.

The default processing action of SIGINT is to terminate the process, and the default processing action of SIGQUIT is to terminate the process and Core Dump (when a process is about to terminate abnormally, you can choose to save all the user space memory data of the process to the disk, the file name is usually core, This is called a Core Dump.).

So how to prove that Ctrl+c and Ctrl+\ correspond to signal 2 SIGINT and signal 3 SIGQUIT respectively?

At this time we can use the signal function

 

 As shown in the figure above, handler is a function pointer, signum is the corresponding signal, and signal can change the processing method of the received signum signal to handler (the format of the handler function needs to correspond to the format defined by the typedef above). And our proof method is to change the processing mode of signals 2 and 3 to handler to verify that Ctrl+c and Ctrl+\ correspond to signal 2 SIGINT and signal 3 SIGQUIT respectively.

 

 As shown in the figure above, we found that Ctrl+c and Ctrl+\ correspond to signal 2 SIGINT and signal 3 SIGQUIT respectively.

 2.2 Call the system function to signal the process

In linux, our command to send a signal is usually named after kill, and the kill command is implemented by calling the kill function. The kill function can send a specified signal to a specified process. The raise function can send a specified signal to the current process (send a signal to yourself).

#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
这两个函数都是成功返回0,错误返回-1。

 The pid of the first parameter of kill refers to the pid of the target process, signo is the signal to be sent, and the signo parameter of rasie is also the object to be sent, but the target is itself. Next we simply use

 The target process looks like this

int main()
{

    /* signal(2,myhandler);
    signal(3,myhandler); */

    while(true)
    {
        cout<<"我是进程,我的pid: "<<getpid()<<endl;
        sleep(1);

    }
    
    return 0;
}

 kill process

int main(int argc, char *argv[])
{
    int signal=atoi(argv[1]);
    int traget_id=atoi(argv[2]);
    int ret1=kill(traget_id,signal);//指令参数读取指令
    assert(ret1==0);
    
    while(true)
    {
        cout<<"我是进程,我的pid: "<<getpid()<<endl;
        sleep(10);
        int ret2=raise(9);
        assert(ret2==0);

    }
    

    return 0;
}

Experimental results

 

 As shown in the figure, kill uses the kill function to kill process 8196 with signal 9, and then calls raise after 10s to kill itself with signal 9

In addition, in addition to the kill and raise interfaces, there is also an abort interface. The abort interface will cause the current process to receive a signal and terminate abnormally.

#include <stdlib.h>
void abort(void);
就像exit函数一样,abort函数总是会成功的,所以没有返回值

2.3 Signals generated by soft conditions

When the process does not meet certain software conditions during running, the OS will send a signal to the process. For example, the read end of the pipe is closed, and the write end is still writing to the pipe. When the write end fills the pipe, the OS will send a signal to the write end. The end process sends a SIGPIPE signal (13), and the default processing method of the process for the SIGPIPE signal is Term (terminate the process). This section mainly introduces the alarm function and the SIGALRM signal.

#include <unistd.h>
unsigned int alarm(unsigned int seconds);

Calling the alarm function can set an alarm clock, that is, tell the kernel to send a SIGALRM signal to the current process after seconds seconds, and the default processing action of the signal is to terminate the current process.

The return value of this function is 0 or the number of seconds remaining from the previously set alarm time . For example, someone wants to take a nap, set the alarm clock to ring after 30 minutes, and is woken up after 20 minutes, and wants to sleep a little longer, so reset the alarm clock to ring after 15 minutes, "previously set The remaining time of the alarm clock time" is 10 minutes. If the seconds value is 0, it means canceling the previously set alarm clock, and the return value of the function is still the remaining seconds of the previously set alarm clock time, let's verify it with a small project

void myhandler(int signal)
{
    cout<<"我的信号是: "<<signal<<endl;
    int n=alarm(10);
    cout<<"闹钟剩余时间: "<<n<<endl;

}

int main()
{
    cout<<"我是进程,我的pid: "<<getpid()<<endl;
    signal(2,myhandler);
    // signal(3,myhandler);
    alarm(10);//十秒后必停止
    while(true)
    {
        sleep(1);
    }
    
    return 0;
}

As shown above, we first replace the processing method of signal 2 with myhandler, then our alarm clock counts down tens of seconds, and the process ends automatically after ten seconds, and in the meantime when we send signal 2, it will automatically call the alarm in myhandler At this time, send signal 2 again, and you can verify the problem of the return value of the alarm

 

 The result is shown above. When we send signal 2, myhandler will call alarm. When we send signal 2 again before the alarm in myhandler rings, we find that the return value of alarm is the remaining time of the last alarm time.

2.4 Signal generated by hardware exception

A hardware exception is somehow detected by the hardware and notified to the kernel, which then sends the appropriate signal to the current process .

 Take our common division by 0 error as an example. When the division by 0 process is running, the data will be loaded to the cpu for calculation, and then the division by 0 will cause the result to overflow. At this time, the overflow detection code of the cpu will be set from 0 to 1. At this time As the manager of hardware and software, the operating system will detect the exception code of the CPU, and then find the process where the exception code is located through the CPU, and send a SIGFPE code to the process to interrupt the process.

 Next, we will use the signal function to verify that the signal corresponding to SIGFPE is 8.

 The result of the operation is as follows

As shown in the figure, first of all, through experiments, we found that the abnormal signal sent by dividing 0 is indeed signal No. 8 (SIGFPE). Secondly, we did not write a loop and only one line divided by 0, but the operating system kept sending us signal No. 8. This is another Why? This is because the process has not been closed, so the overflow detection code in the CPU is always 1, and the operating system will always detect it, causing the operating system to continuously send signals to the process.

 

In addition, we have another discovery, that is, the compiler will have a division by 0 warning during compilation, but it can still be compiled. This is because the division by 0 is detected by the hardware during the running of the process, and it does not belong to the language layer. It belongs to the hardware layer. So the compiler will warn but still compile.

 Summarize

This article mainly leads you to have a simple understanding of signal sending, signal saving, and signal processing , and leads you to understand the four ways of signal sending in depth, and signal saving and signal processing will be released later.

Guess you like

Origin blog.csdn.net/zcxmjw/article/details/131516301