[Linux operating system] Realization of signal capture in Linux system programming

In Linux system programming, signals are an important mechanism for inter-process communication and control. When a certain event occurs, such as the user pressing the Ctrl+C keys, the operating system sends a signal to the process, which the process can catch and handle accordingly. This blog will introduce the classification, capture and processing of signals, as well as the default operation of signals. I hope that through this blog, you can better understand the concept and application of signals in Linux system programming.
insert image description here


1. What is a signal?

In Linux systems, signals are a mechanism for inter-process communication and control. When an event occurs, the kernel sends a signal to the process, and the process can choose to catch and process the signal, or use the default processing method.

Signals can be triggered by various events, such as the user pressing Ctrl+Ca key, an error in the process, or the exit of a child process. Each signal has a unique number, and a predefined default behavior.


2. Classification of signals

  1. Standard Signals : These signals are numbered between 1 and 31 and are defined in the POSIX standard. For example, the SIGINT signal (number 2) is triggered by the user pressing the Ctrl+C key, and the SIGTERM signal (number 15) is the signal used to terminate the process.

  2. Real-time Signals : These signals are numbered between 32 and 63 and are also defined in the POSIX standard. Real-time signals provide higher priority and more precise trigger timing.

  3. User-defined Signals : These signals can be defined by users, and their numbers are greater than 64.


3. Signal processing method

  1. Ignore (Ignore) : The process can choose to ignore a specific signal, so that when the signal occurs, the process will not do anything. However, some signals cannot be ignored, such as SIGKILL and SIGSTOP.

  2. Catch : A process can catch a signal by registering a signal handler. When a signal occurs, the kernel will call the registered signal handler function to handle the signal.

  3. Perform default action (Default Action) : Each signal has a predefined default behavior, such as terminate the process, terminate the process and generate a core dump file, etc.


4. Signal capture and processing

4.1 signal

Role : signalThe function is used to capture and process signals.

Prototype :

#include <signal.h>

void (*signal(int signum, void (*handler)(int)))(int);

Parameters :

  • signum: The signal number to capture.
  • handler: Pointer to the signal handler function.

Return value : Returns the pointer to the previous processing function of the signal. Returns if an error occurs SIG_ERR.

Example : Below is an example that demonstrates how to use signala function to catch and handle the SIGINT signal (the user presses the Ctrl+C keys).

#include <stdio.h>
#include <signal.h>

void sigint_handler(int signum) {
    
    
    printf("Received SIGINT signal\n");
}

int main() {
    
    
    // 注册SIGINT信号的处理函数
    signal(SIGINT, sigint_handler);

    printf("Press Ctrl+C to send SIGINT signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

Example explanation :

  • In the above example, we defined a sigint_handlersignal handler function called . When a SIGINT signal is received, this function is called and a message is printed.
  • In mainthe function, we use signalthe function to register sigint_handlerthe function as a handler for the SIGINT signal. In this way, when the user presses the Ctrl+C key, the operating system will send a SIGINT signal to the process and call sigint_handlera function to handle the signal.
  • In mainthe infinite loop of the function, we wait for the signal to occur. This way, the process runs until it receives a SIGINT signal or other termination signal.
  • When we press the Ctrl+C key, the SIGINT signal will be triggered, the process will call sigint_handlerthe function, and print a message.

4.2 sigaction

Role : sigactionFunction is another way to capture and process signals, signalwhich provides more flexibility and reliability than functions.

Prototype :

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

Parameters :

  • signum: The signal number to capture.
  • act: A struct sigactionpointer to a structure that specifies the new signal handling method.
  • oldact: A struct sigactionpointer to a structure used to save the previous signal processing method.

Return value : If successful, return 0; if error, return -1.

Example : Below is an example that demonstrates how to use sigactiona function to catch and handle the SIGINT signal (the user presses the Ctrl+C keys).

#include <stdio.h>
#include <signal.h>

void sigint_handler(int signum) {
    
    
    printf("Received SIGINT signal\n");
}

int main() {
    
    
    struct sigaction sa;
    sa.sa_handler = sigint_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    // 注册SIGINT信号的处理函数
    sigaction(SIGINT, &sa, NULL);

    printf("Press Ctrl+C to send SIGINT signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

Example explanation :

  • In the above example, we defined a sigint_handlersignal handler function called . When a SIGINT signal is received, this function is called and a message is printed.
  • We create a struct sigactionstruct saand sigint_handlerspecify the function as the signal handler.
  • sigemptysetInitialized with a function sa.sa_mask, which means that there is no need to block other signals when processing the SIGINT signal.
  • sa.sa_flagsSet to 0 to indicate that no special flags are required.
  • Use sigactiona function to saregister a structure as how to handle the SIGINT signal.
  • In mainthe infinite loop of the function, we wait for the signal to occur. This way, the process runs until it receives a SIGINT signal or other termination signal.
  • When we press the Ctrl+C key, the SIGINT signal will be triggered, the process will call sigint_handlerthe function, and print a message.

5. Default Actions for Signals

If a signal is not caught or the caught signal handler returns, the process will perform the default action for the signal.

For example, a process terminates by default when a SIGTERM signal is received. Here is an example demonstrating the default operation of the SIGTERM signal:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sigterm_handler(int signum) {
    
    
    printf("Received SIGTERM signal\n");
}

int main() {
    
    
    // 注册SIGTERM信号的处理函数
    signal(SIGTERM, sigterm_handler);

    printf("Press Ctrl+C to send SIGTERM signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

In the above example, we caught the SIGTERM signal and registered sigterm_handlerthe function as a handler. When a SIGTERM signal is received, this function is called and a message is printed.


Summarize

Signals are a mechanism for inter-process communication and control in Linux systems. We can handle the signal by capturing the signal and registering a handler function. When handling a signal, we can choose to ignore, catch, or perform a default action.

Guess you like

Origin blog.csdn.net/Goforyouqp/article/details/132361279