Linux System Programming 49 Signal-sigprocmask() Set the mask signal mask word of the signal in the signal set

sigprocmask(): Although I don’t know when the signal comes, I can decide when to respond to the signal


Signal collection:

NAME
sigemptyset, sigfillset, sigaddset, sigdelset, sigismember - POSIX signal set operations

SYNOPSIS
#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); 判断 信号是否存在于指定集合中

Signal type: sigset_t


Signal mask word processing

sigprocmask(); // The mask bitmap in the corresponding process of the control signal, the mask bitmap is used to mark whether to respond to each signal, 1 is the response, 0 is the ignore

NAME
       sigprocmask, rt_sigprocmask - examine and change blocked signals

SYNOPSIS
       #include <signal.h>

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

Perform the how action operation on all signals in the set signal set. Oldset retains the state of the signals in the signal set before the signal set operation

 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.

Experiment:
Print one* to standard output every second and print a line feed for five seconds. The program is not affected by the CTRL+C or SIGINT signal, and the SIGINT signal is received in response to the signal to print! .

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

Modification: sigprocmask(SIG_BLOCK...) + sigprocmask(SIG_UNBLOCK...) is
only output between two lines*! , That is, select the time to respond to the SIGINT signal.

#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$ 

Note: between two sigprocmask

sigprocmask(SIG_BLOCK,&set,NULL);

Note that
the SIGINT signal has been shielded between this, that is, the mask signal of SIGINT is shielded at 0, so even if there is a signal, the mask signal shielding bit is bit by bit and the pending signal status bit, the result is also 0, so it does not respond to the action of the SIGINT signal. No printing!

Note 2:
Only when the SIGINT signal is unblocked, that is, when the mask signal is masked to 1, and the program is switched from the kernel mode to the user mode, the result of the mask signal mask bit and the pending signal status bit will be calculated, and respond to the SIGINT signal action To print!

Note 3
And no matter how many SIGINT signals are sent, only one will be printed! , That is, it will only respond to the signal once. This is why the standard signal is lost during the signal response process. The article on the signal response process is very important, the article on the signal response process is very important, and the article on the signal response process is very important. The article on signal response process is critical, and the article on signal response process is critical


sigprocmask(SIG_UNBLOCK,&set,NULL);

And it is important to note that the SIGINT signal will not interrupt the blocked system call in the experiment. Only after SIG_BLOCK, the reason is the same as above, because the signal has been blocked.

: : 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$ 

Same result

The usual approach is: be sure to save and restore the state of the signal set before the modification

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

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/114114857