signal capture

signal function

Function: Register a signal capturing function (register rather than create)

Prototype :

  • sighandler_t signal(int signum, sighandler_t handler);
  • typedef void (*sighandler_t)(int);

Case 1: The signal function captures the ctrl+c trigger event

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<signal.h>

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

void sig_catch(int signo)
{
    printf("catch you!!! %d\n", signo);
    return;
}


int main(int argc, char *argv[])
{
    signal(SIGINT, sig_catch);

    //  
    //
    //
    
    while(1);

    return 0;
}

 sigaction function

Function: Modify the signal processing action (usually used in Linux to register a signal capture function)

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

                Success: 0; Failure: -1, set errno

        parameter:

                act: Pass in parameters, new processing method.

                oldact: outgoing parameters, old processing method

struct sigaction structure

        

        struct sigaction

        {

                void (*sa_handler)(int);

                void     (*sa_sigaction)(int, siginfo_t *, void *);

                sigset_t to_mask;

                int       sa_flags;

                void     (*sa_restorer)(void);

            };

         sa_restorer: This element is obsolete and should not be used. The POSIX.1 standard will not specify this element. (deprecated)

         sa_sigaction: This signal handler is used when sa_flags is specified as the SA_SIGINFO flag. (rarely use) 

Key points to master:

         ① sa_handler: Specify the processing function name after signal capture (i.e. registered function). You can also assign a value to the SIG_IGN table to ignore or the SIG_DFL table to perform the default action.

         ② sa_mask: The set of signals (signal mask words) to be masked when calling the signal processing function. Note: The shielding only takes effect while the processing function is called and is a temporary setting.

         ③ sa_flags: Usually set to 0, the table uses default attributes.

Case 2: The sigaction function  captures the ctrl+c trigger event 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<signal.h>

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

void sig_catch(int signo)  //捕捉函数(回调函数)
{
    if(signo == SIGINT){
         printf(" SIGINT  catch you!!! %d\n", signo);
    } else if(signo == SIGQUIT){
         printf(" SIGQUIT  catch you!!! %d\n", signo);
    }
    return;
}


int main(int argc, char *argv[])
{
    struct sigaction act, oldact;

    act.sa_handler = sig_catch;  //设置回调函数
    sigemptyset(&(act.sa_mask)); //设置屏蔽字 清空sa_mask 在捕捉函数期间生效
    act.sa_flags = 0;            //设置默认属性

    int ret = sigaction(SIGINT, &act, &oldact); //注册信号捕捉函数 ctrl + c
    if(ret == -1){
        sys_err("sigaction error");
    }

    ret = sigaction(SIGQUIT, &act, &oldact); //注册信号捕捉函数 ctrl + \
    
    while(1);

    return 0;
}

Signal Capture Features

  1. When the process is running normally, there is a signal shielding word in the default PCB, assumed to be ☆, which determines which signals the process automatically shields. When a signal capture function is registered, the function must be called after capturing the signal. This function may execute for a long time, and the signals blocked during this period are not specified by ☆. Instead, use sa_mask to specify. After calling the signal processing function, it returns to ☆.
  2. During the execution of the XXX signal capture function, the XXX signal is automatically blocked.
  3. Blocked regular signals do not support queuing, and will only be recorded once if they are generated multiple times. (The last 32 real-time signals support queuing)

Case 3: Verify signal capture characteristics

 From the results, it is easy to see that during the execution of the signal processing function, the signal is delivered multiple times, and then it is processed only once after the end of the processing function.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
void do_sig(int a)
{
    printf("hello world!\n");
    sleep(10);//休息10秒 让函数执行久一点
}
int main(void)
{      
    if (signal(SIGINT, do_sig)== SIG_ERR)
    {
        perror("signal");
        exit(1);
    }
    while (1) {
        printf("---------------------\n");
        sleep(1);
    }
    return 0;
}

 The kernel implements the signal capture process

Guess you like

Origin blog.csdn.net/weixin_43200943/article/details/129843932