linux的sigsetjmp和siglongjmp函数

版权声明:转载请声明 https://blog.csdn.net/qq_40732350/article/details/82701475

一般函数的跳转函数:

int setjmp(jmp_buf env);    //设置跳转点

void longjmp(jmp_buf env, int val);  //起跳

专为信号设置的跳转函数:

void siglongjmp(sigjmp_buf env, int val);        //起跳

int sigsetjmp(sigjmp_buf env, int savesigs);   //设置跳转点

此程序演示了另一种技术,只要在信号处理程序中调用siqlongimp就应使用这种技术。

仅在调用siqsetimp之后才将变量canjump设置为非0值。在信号处理程序中检测此变量,仅当它为非0值时才调用siqlongjmp.这提供了一种保护机制,使得在impbuf (跳转缓冲)尚未由sigsetimp初始化时,防止调用信号处理程序。

(在本程序中, siglongjmp之后程序很快就结束,但是在较大的程序中,在siglongimp之后的较长一段时间内,信号处理程序可能仍旧被设置),在一般的C代码中(不是信号处理程序),对于1ongimp并不需要这种保护措,施。

但是,因为信号可能在任何时候发生,所以在信号处理程序中,需要这种保护措施。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>

static void sig_usr1(int);
static void sig_alrm(int);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump;
int
main(void)
{
	printf("aaaaaaaaa\n");
	if (signal(SIGUSR1, sig_usr1) == SIG_ERR)
		perror("signal(SIGUSR1) error");
	if (signal(SIGALRM, sig_alrm) == SIG_ERR)
		perror("signal(SIGALRM) error");
	printf("starting main: \n"); /* Figure 10.14 */
	//fflush(stdout);
	
	if (sigsetjmp(jmpbuf, 1)) 
	{
		printf("ending main: \n");
		exit(0);
	}
	canjump = 1; /* now sigsetjmp() is OK */
	for ( ; ; )
	{
		pause();
	}
	exit(0);	
}
static void
sig_usr1(int signo)
{
	time_t starttime;
	if (canjump == 0)
		return; /* unexpected signal, ignore */
	printf("starting sig_usr1: \n");
	alarm(3); /* SIGALRM in 3 seconds */
	starttime = time(NULL);
	
	for ( ; ; ) /* busy wait for 5 seconds */
	{
		if (time(NULL) > starttime + 5)
			break;
	}
		
	printf("finishing sig_usr1: \n");
	canjump = 0;
	siglongjmp(jmpbuf, 1); /* jump back to main, don’t return */
}
static void
sig_alrm(int signo)
{
	printf("in sig_alrm: \n");
}

扫描二维码关注公众号,回复: 3323761 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_40732350/article/details/82701475