项目中有一个代码,在数据库(otl_stream)调用open函数时,如果关闭网卡(ifdown eth0),open函数需20分钟才能返回,所以,我们需要有个超时的处理,不幸的是:otl_stream自带的超时机制对此问题无效。
想到用alarm + sigsetjmp的方法。
模拟测试代码:
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
sigjmp_buf jmpbuf;
void sig_alm(int signo)
{
printf("signal let you break out!\n");
siglongjmp(jmpbuf, 1);
}
void print_forever()
{
while (true)
{
printf("I can not stop printing...\n");
}
}
void test()
{
for (int i = 0; i < 7; ++i)
{
printf("I am in [%d]\n", i);
sleep(1);
alarm(1);
if (0 == sigsetjmp(jmpbuf, 1))
{
print_forever();
}
alarm(0);
printf("I am out\n");
sleep(1);
}
}
int main(int argc, char * argv[])
{
if (SIG_ERR == signal(SIGALRM, sig_alm))
{
return(1);
}
printf("start test...\n");
test();
printf("done!\n");
return(0);
}
测试后证明,可以达到效果。
但是,这种方法至少有两个缺陷:
1. Windows下无此机制;
2. 一个进程只能有一个闹钟时间。而这里的open可能在多个子线程中同时调用,那么那些线程间就会相互影响;另外,如果调用模块也有alarm,则更会与调用模块相互影响。
考虑至此,只得作罢。