用C模拟异常
/** * @file test_try_catch.c * @Brief 使用形如C++的异常来检测超时 * @author email:huangkq1989@gmail.com blog:http://blog.csdn.net/kangquan2008 * @version 1.0 * @date 2013-10-22 */ #include <stdio.h> #include <stdlib.h> #include <setjmp.h> #include <signal.h> #include <time.h> #define __WITH_TIME_OUT_IMPOSSIBLE__ #ifdef __WITH_TIME_OUT_IMPOSSIBLE__ static sigjmp_buf __time_out_jump; typedef void (* __sigfunc)(int); static void __do_time_out(int sig) { fprintf(stdout,"time out here\n"); siglongjmp(__time_out_jump, 1); } static void __time_out_reset(__sigfunc store) { alarm(0); signal(SIGALRM, store); } #define TIME_OUT_TRY(x) \ {\ // 设置超时处理函数,将调用longjmp,使得能进入else,即catch __sigfunc save = signal(SIGALRM, __do_time_out);\ // 保存堆栈,返回值为0时表示不是由longjmp返回, // 否则为调用了longjmp后返回的 // 参数 1,是为了保存当前进程的信号屏蔽字 if(!sigsetjmp(__time_out_jump, 1)) {\ //计时 alarm(x); #define TIME_OUT_CATCH \ }\ // 由于sigsetjmp返回非0,进入CATCH else {\ #define TIME_OUT_END \ } \ // 恢复SIGALRM的信号处理函数 __time_out_reset(save);\ } #define TIME_OUT_RETURN(x) { __time_out_reset(save); return (x); } #define TIME_OUT_RETUR_VOID { __time_out_reset(save); return ; } #endif //__WITH_TIME_OUT_IMPOSSIBLE__ int main() { int timeout = 10; TIME_OUT_TRY(timeout) { sleep(11); } TIME_OUT_CATCH{ TIME_OUT_RETURN(-1); } TIME_OUT_END; return 0; }
至于为什么用sigsetjmp而不是setjmp:
如果在信号处理函数中调用异常处理,那么这一信号会加入被屏蔽信号集(信号不排队),当用longjmp退出时,影响了原进程的屏蔽信号集!
补充:软件开发 , C语言 ,