Programação de Sistema Linux 49 Signal-sigprocmask () Define a palavra de máscara de sinal de máscara do sinal no conjunto de sinais

sigprocmask (): Embora eu não saiba quando o sinal chega, posso decidir quando responder ao sinal


Coleta de sinal:

NAME
sigemptyset, sigfillset, sigaddset, sigdelset, sigismember - operações de conjunto de sinal POSIX

SINOPSE
#include <signal.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 sinal: sigset_t


Processamento de texto de máscara de sinal

sigprocmask (); // O bitmap de máscara no processo correspondente do sinal de controle, o bitmap de máscara é usado para marcar se deve responder a cada sinal, 1 é a resposta, 0 é o 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);

Execute a operação de ação como em todos os sinais no conjunto de sinais definido. Oldset retém o estado dos sinais no conjunto de sinais antes de o conjunto de sinais ser operado.

 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.

Experiência:
Imprima um * na saída padrão a cada segundo e imprima uma alimentação de linha por cinco segundos. O programa não é afetado pelo sinal CTRL + C ou SIGINT, e o sinal SIGINT é recebido em resposta ao sinal 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);
}

Modificação: sigprocmask (SIG_BLOCK ...) + sigprocmask (SIG_UNBLOCK ...) é
apenas impresso entre duas linhas *! , Ou seja, selecione o tempo para responder ao sinal 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 duas sigprocmask

sigprocmask (SIG_BLOCK, & set, NULL);

Observe que
o sinal SIGINT foi blindado entre isso, ou seja, o sinal de máscara do SIGINT é blindado em 0, portanto, mesmo se houver um sinal, a blindagem do sinal de máscara é bit a bit e o bit de status do sinal pendente, o resultado também é 0, portanto, não responde à ação do sinal SIGINT. Sem impressão!

Nota 2:
Somente quando o sinal SIGINT é desbloqueado, ou seja, quando o sinal de máscara é mascarado para 1, e o programa é alternado do modo kernel para o modo de usuário, o resultado do bit de máscara do sinal de máscara e o status do sinal pendente bit será calculado e responderá à ação do sinal SIGINT Para imprimir!

Nota 3
E não importa quantos sinais SIGINT sejam enviados, apenas um será impresso! , Ou seja, ele só responderá ao sinal uma vez. É por isso que o sinal padrão é perdido durante o processo de resposta do sinal. O artigo sobre o processo de resposta do sinal é muito importante, o artigo sobre o processo de resposta do sinal é muito importante e o artigo sobre o processo de resposta do sinal é muito importante. O artigo no processo de resposta de sinal é crítico, e o artigo sobre o processo de resposta de sinal é crítico


Sigprocmask (SIG_UNBLOCK, & set, NULL);

E é importante observar que o sinal SIGINT não interromperá a chamada de sistema bloqueada no experimento. Somente após SIG_BLOCK, o motivo é o mesmo acima, pois o sinal foi 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$ 

Mesmo resultado

A abordagem usual é: certifique-se de salvar e restaurar o estado do sinal definido antes da modificação

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

Acho que você gosta

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