Process-signal basic concept and generation function

        Signals are the oldest way of communicating between Linux processes. The signal is a software interrupt, which is a simulation of the interrupt mechanism at the software level, and is an asynchronous communication method. Signals can cause a running process to be interrupted by another running asynchronous process to handle an unexpected event.

        The signal we study here belongs to such an interrupt. When we hit Ctrl + c on the terminal, an interrupt is generated, which is equivalent to a signal, and then this interrupt task will be processed.

The characteristics of the signal:
1. Simple
2. Cannot carry a large amount of information
3. Only when a certain condition is met can it be sent

The signal can directly interact between the user space process and the kernel space process, and the kernel process can use it to notify the user space process of which system events have occurred.

A complete signal cycle includes three parts: the generation of the signal, the registration of the signal in the process, the cancellation of the signal in the process, and the execution of the signal processing function

signal number 

The early version of Unix provided a signal mechanism, but it was unreliable and the signal might be lost. Later, the signal model was changed and a reliable signal mechanism was added, but they were incompatible with each other. POSIX.1 standardized the reliable signal routines

kill -l View signal numbers
Signals 1-31 are called regular signals (also known as ordinary signals or standard signals), 34-64 are called real-time signals, and driver programming is related to hardware.

For the specific signal list, refer to the Linux signal list_baobao8505's blog-CSDN blog_linux signal list

Four elements of a signal

1. Number 2. Name 3. Event 4. Default action

The numbers are different under different operating systems but the names are the same

Action is the default action:

Term: Terminate the process
Ign: Ignore the process
Core: Terminate the process, generate a Core file
Stop: Stop the process
Cont: Continue to run the process

Note: SIGKILL and SIGSTOP signals are not allowed to be ignored and captured, and only default actions can be performed. It can't even be set to block.

After the signal is generated, there are two states 
1. Pending state: Not processed
2. Delivery state: The signal is processed

Blocking Signal Sets and Pending Signal Sets

 The implementation of the signal leads to a strong delay in the signal, but for the user, the time is very short and difficult to detect

The blocking signal set
        adds some signals to the set, and sets shielding for them. When the x signal is shielded, and then the signal is received, the processing of the signal will be postponed (the processing occurs after the shielding is unblocked)

The pending signal set
        signal is generated, and the bit describing the signal in the pending signal set is immediately flipped to 1, indicating that the signal is in a pending state. When the signal is processed the corresponding bit flips back to 0. This moment is often very short.

signal generating function 

kill function

Ordinary users cannot send signals to system users, but super users can send signals to any user

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>

//parent process kill child process
int main(void){
    pid_t pid = -1; 
    
    pid = fork();
    if(-1 == pid){
        perror("fork");
        return 1;
    }   
    
    //child process
    if(0 == pid){
        while(1){
            printf("child process do work...\n");
            sleep(1);
        }

        //exit process
        exit(0);
    }   
    else
    {   
        //parent process

        sleep(3);
        printf("child process is time to exit...\n");
        kill(pid,15);   
        printf("parent process is time to over...\n");
    
    }   

    return 0;
}

Here we use kill to kill the child process after sleep 3 seconds, so it will terminate after executing the do work output 3 times

Send a signal to yourself using the raise function

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

int main(void){
    int i= 1;
    while(1){
        printf("do working %d\n",i);
    
        if(i == 4){ 
            //send a id 15 signal to myself
            raise(SIGTERM);
        }
        i++;
        sleep(1);
    }   

    return 0;
}

Output result: 

do working 1
do working 2
do working 3
do working 4
Terminated

Here we use raise to send a SIGTERM signal to ourselves. If kill is used, then it is
kill(getpid(), SIGTERM); here getpid() is to get the current process id 

abort function

The default is to send the termination signal No. 6 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(void){
    int i = 1;
    while(1){
        printf("do working %d\n",i);

        if(4 == i){ 
            abort();
        }

        i++;
        sleep(1);
    }   
    return 0;
}

Output result: 

do working 1
do working 2
do working 3
do working 4
Aborted (core dumped)

Use alarm to set timeout 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//测试alarm函数
int main(void){
    unsigned int ret = 0;
    
    //第一次设置闹钟 5秒钟之后就超时 发送对应信号
    ret = alarm(5);

    printf("last alarm left time is %u\n",ret);
    
    sleep(2);
    //之前没有超时的闹钟被新的设置给覆盖
    ret = alarm(3);
    printf("last alarm left time is %u\n",ret);

    printf("press any buton continue..\n");
    getchar();
    return 0;
}

last alarm left time is 0
last alarm left time is 3
press any buton continue..
Alarm clock

 Timing has nothing to do with the state of the process, no matter what state the process is in, the alarm will time

setitimer timer

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>


int main(void){
    int ret = -1; 
    struct itimerval tmo;

    tmo.it_value.tv_sec = 3;
    tmo.it_value.tv_usec = 0;

    tmo.it_interval.tv_sec = 2;
    tmo.it_interval.tv_usec = 0;

    ret = setitimer(ITIMER_REAL, &tmo, NULL);
    if(-1 == ret){
        perror("setitimer");
        return 1;
    }   

    printf("press any button to continue...\n");
    getchar();
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43754049/article/details/126146318