Desarrollo multiplataforma (Linux) basado en VS2019 C++ (1.4.3) - blindaje de señal

I. Introducción

Del artículo anterior, sabemos que si se recibe una señal en el núcleo y no hace nada, el proceso se interrumpirá. En este momento, la señal debe protegerse.

2. Prototipo de función

1. función sigprocmask 

Archivo de encabezado: #include <signal.h>

Función: lea o cambie la palabra de protección de la señal del proceso y proteja las señales no reconocidas o no deseadas para garantizar la ejecución normal del proceso.
Prototipo: int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

Descripción de parámetros:

        Si oset es un puntero no nulo, la máscara de señal actual del proceso de lectura pasa a través del parámetro oset. Si el conjunto es un puntero no nulo, la máscara de señal del proceso se cambia y el parámetro cómo indica cómo cambiar. Si oset y set son punteros no nulos, primero haga una copia de seguridad de la palabra de máscara de señal original en oset y luego cambie la palabra de máscara de señal de acuerdo con los parámetros set y how. Suponiendo que la palabra de máscara de señal actual sea mask, la siguiente tabla describe los valores opcionales del parámetro how.

Valor devuelto: 0 en caso de éxito, -1 en caso de error

Parámetro cómo valor opcional
SIG_BLOCK Señal bloqueada (blindada)
SIG_UNBLOCK La señal no está bloqueada (desbloqueada)
SIG_SETMASK Establecer la palabra de máscara de señal actual en el valor señalado por set es equivalente a establecer la palabra de máscara de señal actual en el valor señalado por set

La función de operación del conjunto de señales es la siguiente

#include <signal.h>
/* Clear all signals from SET.  */
int sigemptyset(sigset_t *set);// 清空信号集
 /* Set all signals in SET.  */
int sigfillset(sigset_t *set);// 所有信号加进去 32 33 是没有的
int sigaddset(sigset_t *set, int signo);// 增加信号
int sigdelset(sigset_t *set, int signo);//删除信号集的某个信号
int sigismember(const sigset_t *set, int signo);// 信号是否在集合里面
 /* Return 1 if SIGNO is in SET, 0 if not.  */

Ejemplo

1. Implementar los pasos básicos

  • Primero prepare un conjunto de señales (que puede entenderse como un contenedor para proteger las señales o como agregar amigos a la lista negra)
  • Inicialización del contenedor de señal
  • Agregar una señal enmascarada
  • Llame a sigprocmask para enmascarar el conjunto de señales establecido

2. Código

    //准备信号容器
	sigset_t arr;
	//容器初始化
	sigemptyset(&arr);
	//添加屏蔽的信号
	sigaddset(&arr,SIGUSR1);
	sigaddset(&arr, SIGUSR2);

	if (sigprocmask(SIG_BLOCK,&arr,NULL) < 0)
	{
		perror("sigprocmask error");
		exit(0);
	}
	while (true)
	{
		cout << "当前进程运行中 ...pid =" << getpid() << endl;
		sleep(1);
	}

3. Efecto de operación

Como se puede ver en la siguiente figura, las señales siempre se envían al proceso en este momento y no se interrumpirán.

4. Análisis

A través del ejemplo anterior, bloquear la señal es realmente como una chica que pone a su novio en la lista negra, pero la chica quiere saber si su novio la llamó y le envió un mensaje (quizás si se vuelve blanda, será eliminada de la lista negra). Luego, si desea saber si hay una conexión, debe usar la función sigpending, de la siguiente manera

2. función pendiente

#include <señal.h>
int sigpending(sigset_t *set);

Función: Leer el conjunto de señales pendientes del proceso actual (pendiente significa que la señal aún no se ha vinculado al controlador de respuesta, es decir, no se decide si eliminarlo de la lista negra o mantenerlo en la lista negra para siempre, solo quiero verlo ¿Hay alguna conexión al final)
Valor devuelto: 0 si tiene éxito, -1 si hay error 

 Ejemplo

1. Código

    //准备信号容器
	sigset_t arr;
	//容器初始化
	sigemptyset(&arr);
	//添加屏蔽的信号
	sigaddset(&arr,SIGUSR1);
	sigaddset(&arr, SIGUSR2);

	if (sigprocmask(SIG_BLOCK,&arr,NULL) < 0)
	{
		perror("sigprocmask error");
		exit(0);
	}


	while (true)
	{
		cout << "当前进程运行中 ...pid =" << getpid() << endl;
		sleep(10);
		//查看未决信号集(黑名单)
		if (sigpending(&arr) == 0)
		{
			//判断未决信号是谁发的
			cout << "黑名单中的电话打来"  << endl;
			if (sigismember(&arr,SIGUSR1))
			{
				cout << "黑名单中的SIGUSR1打来电话" << endl;
			}
			if (sigismember(&arr, SIGUSR2))
			{ 
				cout << "黑名单中的SIGUSR2打来电话" << endl;
			}
		}
	}
	

	return 0;

Aviso:

①if (sigpending(&arr) == 0) es solo para juzgar si la función se puede ejecutar con éxito, no si la señal se coloca con éxito en el conjunto de señales

② Parece que el conjunto de señales pendientes (señal sin procesar) no se puede vaciar con sigemptyset (queda en estudio)

2. Ejecución de resultados

Como se muestra en la figura a continuación, se envían cuatro señales al proceso 10431, y el proceso muestra quién envió la señal (en este momento, la chica sabe que el novio en la lista negra ha llamado varias veces)

 

Supongo que te gusta

Origin blog.csdn.net/hml111666/article/details/123683046
Recomendado
Clasificación