函数setjmp,longjmp和sigsetjmp,siglongjmp

int sigsetjmp(sigjmp_buf env,int savemask);

                                                      返回值:若直接调用则返回0,若从siglongjmp调用返回则返回非0值;

int siglongjmp(sigjmp_buf env,int val);

setjmp和longjmp的使用如下:

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

#define MAXLINE 1024

void sig_alarm(int signo);

jmp_buf env_alrm;
int main() {
	int n;
	char buf[MAXLINE];
	if (signal(SIGALRM, sig_alarm) == SIG_ERR) {
		printf("can't catch sigalrm\n");
		exit(0);
	}
	if (setjmp(env_alrm) != 0) {
		printf("longjump called\n");
		exit(0);
	}
	alarm(5);
	if ((n = read(STDIN_FILENO, buf, MAXLINE)) < 0) {
		printf("read error\n");
		exit(0);
	}
	alarm(0);
	write(STDOUT_FILENO, buf, n);
}

void sig_alarm(int signo) {
	longjmp(env_alrm, 1);
}


 

也可以用在sleep函数中:

 

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

static jmp_buf env_alrm;

static void sig_alrm(int signo) {
	longjmp(env_alrm, 1);
}

unsigned int sleep2(unsigned int secs) {
	if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
		return (nsecs);
	}
	if (setjmp(env_alrm) == 0) {
		alarm(nsecs);
		pause();
	}
	return (alarm(0));
}


sigsetjmp和siglongjmp使用基本相同,只是siglongjmp比setjmp多一个参数,若savemask为非0值,则sigsetjmp在env中保存进程的当前屏蔽字。若调用siglongjmp时,如果带非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中回复保存的信号屏蔽字。

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

//SIGINT,SIGQUIT,SIGUSR1,SIGALRM
//siglongjmp longjmp
//siglongjmp can handle singal automatic
void sig_alarm(int signo);
void sig_usr1(int signo);
void pr_mask(const char *str);
jmp_buf jmp_aaa;
static int canjmp = 0;

int main() {
	pr_mask("start pro");
	if (signal(SIGALRM, sig_alarm) == SIG_ERR) {
		printf("can't catch sigalrm\n");
		exit(0);
	}
	if (signal(SIGUSR1, sig_usr1) == SIG_ERR) {
		printf("can't catch sigusr1\n");
		exit(0);
	}
	if (sigsetjmp(jmp_aaa, 1) != 0) {
		//if (setjmp(jmp_aaa) != 0) {
		pr_mask("end pro");
		exit(0);
	}
	canjmp = 1;
	raise(SIGUSR1);
	return 0;
}

void sig_alarm(int signo) {
	pr_mask("in sig_alarm");
}

void sig_usr1(int signo) {
	if (canjmp == 0) {
		return;
	}
	pr_mask("before sigalrm");
	alarm(3);
	sleep(5);
	pr_mask("after sigalrm");
	siglongjmp(jmp_aaa, 1);
	//longjmp(jmp_aaa, 1);
}
void pr_mask(const char *str) {
	printf("%s\n", str);
	sigset_t curset;
	if (sigprocmask(0, NULL, &curset) < 0) {
		printf("call sigprocmask error\n");
	}
	if (sigismember(&curset, SIGINT))
		printf("SIGINT\n");
	if (sigismember(&curset, SIGQUIT))
		printf("SIGQUIT\n");
	if (sigismember(&curset, SIGUSR1))
		printf("SIGUSR1\n");
	if (sigismember(&curset, SIGALRM))
		printf("SIGALRM\n");
}


 

posted on 2012-06-25 21:05  java课程设计  阅读(325)  评论(0编辑  收藏  举报

导航