2010年(5)
分类: C/C++
2010-01-19 13:31:40
|
man 手册中关于函数的描述:
setjmp() saves the stack context/environment in env for later use by longjmp(3).sigsetjmp() is similar to setjmp(). If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp(3) is later performed with this env.
网上关于sigsetjmp & siglongjmp的使用例子已经很多,但我觉得他们少写了一点,至少这于我这种才使用该函数的人是很重要的,而且telnet源码中也使用了此方法。网上的例子都是在同一源文件的不同函数中使用sigsetjmp & siglongjmp,但我觉得这种例子还不能完全明白的诠释出它们的用法。因为用goto也能达到同样目的。下面,是在两个不同源文件例用sigsetjmp & siglon-gjmp的例子,希望对各位能有所帮助。
源文件A:sigsetjmp.c
#include
#include
#include
sigjmp_buf sigBuf;
void FunA()
{
printf("Enter FunA!\n");
call();
printf("Exit FunA!\n");
}
int main(int argc,char *argv[])
{
int iRet = 0;
iRet = sigsetjmp(sigBuf,1);
if (0 == iRet)
{
FunA();
}
else if (iRet != 0)
{
printf("program close!\n");
}
return 0;
}
源文件B:call.c
#include
#include
extern sigjmp_buf sigBuf;
void call()
{
printf("Enter call!\n");
siglongjmp(sigBuf,1);
printf("Exit call!\n");
}
[root@localhost sigsetjmp]#
编译:
[root@localhost sigsetjmp]# gcc -o sigsetjmp sigsetjmp.c call.c
[root@localhost sigsetjmp]#
运行:
[root@localhost sigsetjmp]# ./sigsetjmp
Enter FunA!
Enter call!
program close!
[root@localhost sigsetjmp]#
但如果把call()改为
void call()
{
printf("Enter call!\n");
printf("Exit call!\n");
}
编译、运行结果如下:
[root@localhost sigsetjmp]# ./sigsetjmp
Enter FunA!
Enter call!
Exit call!
Exit FunA!
[root@localhost sigsetjmp]#
上面的结果说明在不同源文件中使用sigsetjmp & siglongjmp,明显的改变了程序的顺序执行流程,能达到类似goto的效果。
另外:
对于man手册中这句我没有理解:
If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp(3) is later performed with this env.
如查savesigs非0,那个阻塞信号将会保存在env中并于siglongjmp调用时恢复。
我用sigsetjmp_signal.c试了一下,将SIGINT的信号阻塞,但调用siglongjmp并没用调用SIGINT的处理函数。有知道的朋友希望回复我一下,十分感谢。
源文件:sigsetjmp_signal.c
#include
#include
#include
sigjmp_buf sigBuf;
void FunB()
{
printf("Enter FunB!\n");
printf("Exit FunB!\n");
}
void FunA()
{
printf("Enter FunA!\n");
call();
printf("Exit FunA!\n");
}
int main(int argc,char *argv[])
{
int iRet = 0;
struct sigaction act;
sigset_t stSig;
sigemptyset(&stSig);
sigaddset(&stSig, SIGINT);
sigprocmask(SIG_BLOCK, &stSig, NULL);/*阻塞信号SIGINT*/
act.sa_handler = FunB;/*指定SIGINT信号响应函数*/
act.sa_flags = SA_INTERRUPT;
sigemptyset(&act.sa_mask);
if (sigaction(SIGINT,&act,NULL) != 0)
{
perror("sigaction");
}
iRet = sigsetjmp(sigBuf,1);
if (0 == iRet)
{
kill(getpid(),SIGINT);
FunA();
}
else if (iRet != 0)
{
printf("program close!\n");
}
return 0;
}
上传文件为例子中使用源码,本人水平有限,发文目的纯属交流,希望高手勿拍砖。