Signal processing function returns Linux-

Executing the signal handler how to do

Generally, the signal processing function completes will return to normal, other functions can call the function returns to the main program. Summarize hereAfter completion of the jump to the main signal processing function performs the function specified in the operator's position(Somewhat similar to the goto statement, but does not support goto jump between functions, only to jump in a function), mainly through two of the function to achieve:

  • setjmp()/longjmp()
  • sigsetjmp()/siglongjmp()

The following two sets of function analysis.

setjmp()/longjmp()

The signal processing function in longjmp()the function of the signal processing functions can jump directly to setjmp()a function of position, maybe prototype functions as follows:

#include <setjmp.h>

int setjmp( jmp_buf env );
void longjmp( jmp_buf env, int val );
  • Env parameter is a global variable,Is stored when you call longjmp () can be used to restore all of the information stack status, users do not need to configure this parameter, longjmp () will automatically be put into your account information
  • Parameter val, the longjmp () jump to setjmp (), thesetjmp () return value is the value of val, When the plurality of longjmp () jump, by judgment setjmp (return value can be determined) from where the jump.

By following a procedure to analyze the setjmp () / longjmp () usage and shortcomings:

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>

/* 全局变量 */
jmp_buf env;

/* SIGRTMIN+15的处理函数 */
void handler_sigrtmin15( int signo )
{
	printf("recv SIGRTMIN+15\n");
	/* setjmp的返回值是1 */
	longjmp( env, 1 );
}

/* SIGRTMAX-15的处理函数 */
void handler_sigrtmax15( int signo )
{
	printf("recv SIGRTMAX-15\n");
	/* setjmp返回值是2 */
	longjmp( env, 2 );
}

int main( void )
{
	/* 通过switch判断setjmp的返回值 */
	switch( setjmp( env ) )
	{
		case 0:
			break;
		case 1 :
			printf("return from SIGRTMIN+15\n");
			break;
		case 2:
			printf("return from SIGRTMAX-15\n");
			break;
		default :
		break;
	}
	/* 安装俩个信号的信号处理函数 */
	signal( SIGRTMIN+15, handler_sigrtmin15 );
	signal( SIGRTMAX-15, handler_sigrtmax15 );
	while( 1 )
		;
	return 0;
}

Then open a terminal and enter ps -athe implementation view the process ID, the program is as follows:
Here Insert Picture Description

As can be seen, the process in another station can transmit information to the process ID, the two pieces of information about each transmission time, also showing the received two pieces of information

However, if the two pieces repeatedly sent signals to the process, the output process will increase it? Here are sending multiple signals, the status of implementation of the process:
Here Insert Picture Description
status of implementation of natural goose, the process has not changed!
- == Why send multiple signals, only a feedback signal it ==?
As mentioned above, when the process when processing signals, blocks the current signal (ie, received no treatment), when the signal handler is finished (normal returns), will unblock the current signal and then processing the signal blocking (pending signal queue). Further SIGRTMIN + 15 and SIGRTMAX-15 is a reliable signal, i.e. support line (the signal is not lost when blocked), it stands to reason that the signal processing performed after completion of a pending signal will then be processed in the queue, the actual on only the first signal processing.

  • Why only processed the first time the signal is no longer signal the pending signal queue to handle it?
    The reason is that the signal processing function does not return to normal, resulting in blocking of the signal is not released, so that signal processing function is executed only once.
  • Why the signal handler does not return it to normal?
    the reason is,longjmp () function is to jump directly to the setjmp () location, not a return to normal, so the first time there will be no blocking signal is set to liftUnless manually unblocked.

So, while setjmp () / longjmp () can be achieved skip signal processing functions, but can not be unblocked signals after the jump, so there sigsetjmp () / siglongjmp () function, which not only signal processing function can be achieved Jump can also unblock signal.

sigsetjmp () / siglongjmp ()

Use sigsetjmp () / siglongjmp () and setjmp () / longjmp () is very similar, sigsetjmp () / siglongjmp () function prototype is as follows:

#include <setjmp.h>

int sigsetjmp( sigjmp_buf env, int savesigs );
void siglongjmp( sigjmp_buf env, int val );
  • Parameters and setjmp () / longjmp () function in the same
  • The only difference is that the parameters savesigs,When non-zero, when calling sigsetjmp () on the signal will be unblocked

By following a familiar program at sigsetjmp () / siglongjmp () is used:

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

#define ENV_UNSAVE  0
#define ENV_SAVED   1
int flag_saveenv = ENV_UNSAVE;
/* 保存跳转位置的栈信息 */
jmp_buf env;

void handler_sigrtmin15( int signo )
{
	if( flag_saveenv == ENV_UNSAVE )
		return ;
	printf("recv SIGRTMIN+15\n");
	sleep( 10 );
	printf("in handler_sigrtmin15, after sleep\n");
	/* 第二个参数非0,就在调用sigsetjmp后解除信号阻塞 */
	siglongjmp( env, 1 );
}

int main( void )
{
	switch( sigsetjmp( env, 1 ) )
	{
		case 0:
			printf("return 0\n");
			flag_saveenv = ENV_SAVED;
			break;
		case 1:
			printf("return from SIGRTMIN+15\n");
			break;
		default :
			printf("return else\n");
			break;
	}
	/* 安装信号处理函数 */
	signal( SIGRTMIN+15, handler_sigrtmin15 );
	while( 1 )
		;
	return 0;
}

The implementation process is as follows:
Here Insert Picture Description
As can be seen, the process for all signals responded, but only print out a return from SIGRTMIN+15Why is this?
Because the signals are sent four times (sleep), so after three signals are pending signal queue, when the signal processing functions processed first signal, the signal processing will first check whether the function of sleep when there is a pending signal If there is, first deal pending, and back again. So After performing the first signal processing, there are three times followed by the implementation of signal processing functions, and only then jumps to print information at sigsetjmp.
To sum up:
there is pending before a response back

Published 62 original articles · won praise 188 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43743762/article/details/101374036