Programación del sistema Linux 49 Signal-sigprocmask () Establece la palabra de máscara de señal de máscara de la señal en el conjunto de señales

sigprocmask (): aunque no sé cuándo llega la señal, puedo decidir cuándo responder a la señal


Colección de señales:

NOMBRE
sigemptyset, sigfillset, sigaddset, sigdelset, sigismember - operaciones de conjunto de señales POSIX

SINOPSIS
#include <señal.h>

   int sigemptyset(sigset_t *set);  清空信号集

   int sigfillset(sigset_t *set); 填充满 信号集

   int sigaddset(sigset_t *set, int signum); 向信号集中添加信号

   int sigdelset(sigset_t *set, int signum); 从型号集中删除信号

   int sigismember(const sigset_t *set, int signum); 判断 信号是否存在于指定集合中

Tipo de señal: sigset_t


Procesamiento de texto de máscara de señal

sigprocmask (); // El mapa de bits de la máscara en el proceso correspondiente de la señal de control, el mapa de bits de la máscara se usa para marcar si se debe responder a cada señal, 1 es la respuesta, 0 es el ignorar

NAME
       sigprocmask, rt_sigprocmask - examine and change blocked signals

SYNOPSIS
       #include <signal.h>

       int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

Realice la operación de acción de cómo en todas las señales en el conjunto de señales establecido. Oldset retiene el estado de las señales en el conjunto de señales antes de que se opere el conjunto de señales.

 The behavior of the call is dependent on the value of how, as follows.

   SIG_BLOCK 对目标信号集中的所有信号进行阻塞,即将mask信号屏蔽位置0
          The set of blocked signals is the union of the current set and the set argument.

   SIG_UNBLOCK  对目标信号集中的所有信号解除阻塞  即将mask信号屏蔽位置1
          The signals in set are removed from the current set of blocked signals.  It is permissible to attempt to unblock a signal which is not blocked.

   SIG_SETMASK  回复信号集之前的状态,并保存信号集恢复之前的当前状态
          The set of blocked signals is set to the argument set.

RETURN VALUE  0为成功,-1为失败
   sigprocmask() returns 0 on success and -1 on error.  In the event of an error, errno is set to indicate the cause.

Experimento:
Imprima uno * en salida estándar cada segundo e imprima un avance de línea durante cinco segundos. El programa no se ve afectado por la señal CTRL + C o SIGINT, y la señal SIGINT se recibe en respuesta a la señal para imprimir. .

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

void sig_handler(int s)
{
	write(1,"!",1);
}

int main()
{
	int i,j;

	signal(SIGINT,sig_handler);
	for(j=0;j < 1000;j++)
	{

		for(i=0 ; i<5 ; i++)
		{
			write(1,"*",1);
			sleep(1);
		}	
		write(1,"\n",1);
	}


	exit(0);
}

Modificación: sigprocmask (SIG_BLOCK ...) + sigprocmask (SIG_UNBLOCK ...)
solo se emite entre dos líneas *! , Es decir, seleccione el tiempo para responder a la señal SIGINT.

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


void sig_handler(int s)
{
	write(1,"!",1);
}

int main()
{
	int i,j;
	sigset_t set;//创建信号集

	signal(SIGINT,sig_handler);
	
	sigemptyset(&set); //清空信号集
	sigaddset(&set,SIGINT); // 添加 SIGINT信号 到信号集


	for(j=0;j < 1000;j++)
	{

		sigprocmask(SIG_BLOCK,&set,NULL); // 对 set信号集中的信号 进行阻塞,即将mask信号屏蔽位置0
		for(i=0 ; i<5 ; i++) 
		{
			write(1,"*",1);
			sleep(1);
		}	
		write(1,"\n",1);
		sigprocmask(SIG_UNBLOCK,&set,NULL); // 对 set信号集中的信号 解除阻塞,即将mask信号屏蔽位置1
	}


	exit(0);
}


mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ gcc sigprocmask.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ ./a.out 
***^C*^C*^C^C^C^C^C
!*^C^C^C^C^C^C*^C^C^C^C^C^C*^C**
!*****
*^C*^C^C^C^C^C*^C^C*^C*
!*****
*****
*****
*****
*****
****^C*^C
!***^C^C**
!*****^\Quit (core dumped)
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ 

Nota: entre dos sigprocmask

sigprocmask (SIG_BLOCK, & set, NULL);
...

Tenga en cuenta que
la señal SIGINT se ha blindado entre esto, es decir, la señal de máscara de SIGINT está blindada en 0, por lo que incluso si hay una señal, el blindaje de la señal de máscara bit a bit y el bit de estado de la señal pendiente, el resultado también es 0, por lo que no responde a la acción de la señal SIGINT.

Nota 2:
Solo cuando la señal SIGINT está desbloqueada, es decir, cuando la señal de máscara está enmascarada a 1, y el programa cambia del modo de núcleo al modo de usuario, el resultado del bit de máscara de la señal de máscara y el estado de la señal pendiente. Se calculará el bit y responderá a la acción de la señal SIGINT Para imprimir!

Nota 3
Y no importa cuántas señales SIGINT se envíen, ¡solo se imprimirá una! Es decir, solo responderá a la señal una vez. Esta es la razón por la que la señal estándar se pierde durante el proceso de respuesta de la señal. El artículo sobre el proceso de respuesta de la señal es muy importante, el artículo sobre el proceso de respuesta de la señal es muy importante y el artículo sobre el proceso de respuesta de la señal es muy importante. sobre el proceso de respuesta a la señal es fundamental, y el artículo sobre el proceso de respuesta a la señal es fundamental


Sigprocmask (SIG_UNBLOCK, & set, NULL);

Y es importante tener en cuenta que la señal SIGINT no interrumpirá la llamada al sistema bloqueada en el experimento. Solo después de SIG_BLOCK, el motivo es el mismo que el anterior, porque la señal se ha bloqueado.

: : Sigprocmask (SIG_BLOCK…) + sigprocmask (SIG_SETMASK…)

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


void sig_handler(int s)
{
	write(1,"!",1);
}

int main()
{
	int i,j;
	sigset_t set,oset;//创建信号集

	signal(SIGINT,sig_handler);
	
	sigemptyset(&set); //清空信号集
	sigaddset(&set,SIGINT); // 添加 SIGINT信号 到信号集


	for(j=0;j < 1000;j++)
	{

// 对 set信号集中的信号 进行阻塞,即将mask信号屏蔽位置0. 并且将 信号集阻塞之前的状态保存到 oset
		sigprocmask(SIG_BLOCK,&set,&oset); 
		for(i=0 ; i<5 ; i++) 
		{
			write(1,"*",1);
			sleep(1);
		}	
		write(1,"\n",1);

//即 恢复 oset信号集,即解除阻塞
		sigprocmask(SIG_SETMASK,&oset,NULL); 
	}


	exit(0);
}


mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ gcc sigprocmask.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ ./a.out 
***^C*^C*^C^C^C^C^C
!*^C^C^C^C^C^C*^C^C^C^C^C^C*^C**
!*****
*^C*^C^C^C^C^C*^C^C*^C*
!*****
*****
*****
*****
*****
****^C*^C
!***^C^C**
!*****^\Quit (core dumped)
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ 

Mismo resultado

El enfoque habitual es: asegúrese de guardar y restaurar el estado de la señal establecida antes de la modificación

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


void sig_handler(int s)
{
	write(1,"!",1);
}

int main()
{
	int i,j;
	sigset_t set,saveset;//创建信号集

	signal(SIGINT,sig_handler);
	
	sigemptyset(&set); //清空信号集
	sigaddset(&set,SIGINT); // 添加 SIGINT信号 到信号集

//在当前模块修改之前 保存信号集状态,以便 当前模块执行完成后恢复 信号集状态
sigprocmask(SIG_UNBLOCK,&set,&saveset);

	for(j=0;j < 1000;j++)
	{

		sigprocmask(SIG_BLOCK,&set,NULL); // 对 set信号集中的信号 进行阻塞,即将mask信号屏蔽位置0
		for(i=0 ; i<5 ; i++) 
		{
			write(1,"*",1);
			sleep(1);
		}	
		write(1,"\n",1);
		sigprocmask(SIG_UNBLOCK,&set,NULL); // 对 set信号集中的信号 解除阻塞,即将mask信号屏蔽位置1
	}

// 恢复 之前信号集状态
sigprocmask(SIG_SETMASK,&saveset,NULL);

	exit(0);
}

Supongo que te gusta

Origin blog.csdn.net/LinuxArmbiggod/article/details/114114857
Recomendado
Clasificación