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