Cross-platform (Linux) development based on VS2019 C++ (1.4.3) - signal shielding

I. Introduction

From the previous article, we know that if a signal is received in the kernel and does not do anything, the process will be interrupted. At this time, the signal needs to be shielded.

2. Function prototype

1. sigprocmask function 

Header file: #include <signal.h>

Function: Read or change the signal shielding word of the process, and shield the unrecognized or undesired signals to ensure the normal execution of the process.
Prototype: int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

Parameter Description:

        If oset is a non-null pointer, the current signal mask of the reading process is passed out through the oset parameter. If set is a non-null pointer, the signal mask of the process is changed, and the parameter how indicates how to change. If both oset and set are non-null pointers, first back up the original signal mask word to oset, and then change the signal mask word according to the set and how parameters. Assuming that the current signal mask word is mask, the following table describes the optional values ​​of the how parameter.

Return value: 0 on success, -1 on error

Parameter how optional value
SIG_BLOCK Signal locked (shielded)
SIG_UNBLOCK Signal is not locked (unblocked)
SIG_SETMASK Setting the current signal mask word to the value pointed to by set is equivalent to setting the current signal mask word to the value pointed to by set

The signal set operation function is as follows

#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.  */

Example

1. Implement the basic steps

  • First prepare a signal set (which can be understood as a container for shielding signals or as adding friends to the blacklist)
  • Signal container initialization
  • Add a masked signal
  • Call sigprocmask to mask the set signal set

2. Code

    //准备信号容器
	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. Operation effect

As can be seen from the figure below, signals are always sent to the process at this time and will not be interrupted

4. Analysis

Through the above example, blocking the signal is really like a girl pulling her boyfriend into the blacklist, but the girl wants to know if her boyfriend has called and sent her a message (maybe if she becomes soft-hearted, she will be removed from the blacklist). Then if you want to know if there is a connection, you have to use the sigpending function, as follows

2. sigpending function

#include <signal.h>
int sigpending(sigset_t *set);

Function: Read the pending signal set of the current process (pending means that the signal has not yet been bound to the response handler, that is, it is not decided whether to remove him from the blacklist or keep him in the blacklist forever, just want to see him Is there any connection in the end)
Return value: 0 if successful, -1 if error 

 Example

1. Code

    //准备信号容器
	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;

Notice:

①if (sigpending(&arr) == 0) is only to judge whether the function can be executed successfully, not whether the signal is successfully put into the signal set

② It seems that the pending signal set (unprocessed signal) cannot be emptied with sigemptyset (for further study)

2. Running results

As shown in the figure below, four signals are sent to the 10431 process, and the process shows who sent the signal (at this time, the girl knows that the boyfriend in the blacklist has called several times)

 

Guess you like

Origin blog.csdn.net/hml111666/article/details/123683046