Concepto básico de señales de proceso y función de generación.

        Las señales son la forma más antigua de comunicación entre procesos de Linux. La señal es una interrupción de software, que es una simulación del mecanismo de interrupción a nivel de software y es un método de comunicación asincrónico. Las señales pueden hacer que un proceso en ejecución sea interrumpido por otro proceso asincrónico en ejecución para manejar un evento inesperado.

        La señal que estudiamos aquí pertenece a dicha interrupción. Presionamos Ctrl + c en el terminal para generar una interrupción, lo que equivale a generar una señal, y luego se procesará esta tarea de interrupción.

Las características de la señal:
1. Simple
2. No puede transportar una gran cantidad de información
3. Solo cuando se cumple una determinada condición se puede enviar

La señal puede interactuar directamente entre el proceso del espacio del usuario y el proceso del espacio del kernel, y el proceso del kernel puede usarla para notificar al proceso del espacio del usuario qué eventos del sistema han ocurrido.

Un ciclo completo de señal incluye tres partes: la generación de la señal, el registro de la señal en el proceso, la cancelación de la señal en el proceso y la ejecución de la función de procesamiento de la señal.

número de señal 

La primera versión de Unix proporcionaba un mecanismo de señal, pero no era confiable y la señal podía perderse. Más tarde, se cambió el modelo de señal y se agregó un mecanismo de señal confiable, pero eran incompatibles entre sí. POSIX.1 estandarizó lo confiable rutinas de señal

kill -l Ver números de señal
Las señales 1 a 31 se denominan señales regulares (también conocidas como señales ordinarias o señales estándar), 34 a 64 se denominan señales en tiempo real y la programación del controlador está relacionada con el hardware.

Para obtener la lista de señales específicas, consulte la lista de señales de Linux_baobao8505's blog-CSDN blog_linux lista de señales

Cuatro elementos de una señal.

1. Número 2. Nombre 3. Evento 4. Acción predeterminada

Los números son diferentes en diferentes sistemas operativos pero los nombres son los mismos

La acción es la acción predeterminada:

Término: finalizar el proceso
Ign: ignorar el proceso
Core: finalizar el proceso, generar un archivo principal
Detener: detener el proceso
Cont: continuar ejecutando el proceso

Nota: No se permite ignorar ni capturar las señales SIGKILL y SIGSTOP, y solo se pueden realizar acciones predeterminadas. Ni siquiera se puede configurar para bloquear.

Después de generar la señal, hay dos estados 
1. Estado pendiente: No procesado
2. Estado de entrega: La señal está procesada

Bloqueo de conjuntos de señales y conjuntos de señales pendientes

 La implementación de la señal provoca un fuerte retraso en la señal, pero para el usuario el tiempo es muy corto y difícil de detectar.

El conjunto de señales de bloqueo
        agrega algunas señales al conjunto y establece el blindaje para ellas. Cuando la señal x está blindada y luego se recibe la señal, el procesamiento de la señal se pospondrá (el procesamiento ocurre después de que se desbloquea el blindaje)


        Se genera la señal del conjunto de señales pendientes y el bit que describe la señal en el conjunto de señales pendientes se cambia inmediatamente a 1, lo que indica que la señal está en un estado pendiente. Cuando se procesa la señal, el bit correspondiente vuelve a 0. Este momento suele ser muy breve.

función de generación de señal 

función de matar

Los usuarios normales no pueden enviar señales a los usuarios del sistema, pero los superusuarios pueden enviar señales a cualquier usuario.

#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;
}

Aquí usamos kill para matar el proceso hijo después de dormir 3 segundos, por lo que finalizará después de ejecutar la salida do work 3 veces.

Envíate una señal a ti mismo usando la función de subir

#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;
}

Resultado de salida: 

hacer trabajo 1
hacer trabajo 2
hacer trabajo 3
hacer trabajo 4
Terminado

Aquí usamos rise para enviarnos una señal SIGTERM a nosotros mismos. Si se usa kill, entonces es
kill(getpid(), SIGTERM); aquí getpid() es para obtener la identificación del proceso actual. 

función de aborto

El valor predeterminado es enviar la señal de terminación 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;
}

Resultado de salida: 

hacer trabajo 1
hacer trabajo 2
hacer trabajo 3
hacer trabajo 4
Abortado (núcleo volcado)

Utilice la alarma para establecer el tiempo de espera 

#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;
}

El tiempo restante de la última alarma es 0.
El tiempo restante de la última alarma es 3.
Presione cualquier botón para continuar.
Despertador

 El tiempo no tiene nada que ver con el estado del proceso, no importa en qué estado se encuentre el proceso, la alarma sonará.

temporizador configurador

#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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43754049/article/details/126146318
Recomendado
Clasificación