这是我的代码:
#define _OPEN_SYS
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
volatile int footprint = 0;
void catcher(int signum) {
puts("inside signal catcher!");
alarm(0);
footprint = 1;
return;
}
main() {
printf("footprint=%dn", footprint);
struct sigaction sact;
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = catcher;
if (footprint == 0) {
puts("the signal catcher never gained control");
sigaction(SIGALRM, &sact, NULL);
printf("before loop");
alarm(5); /* timer will pop in five seconds */
while (true);
} else
puts("the signal catcher gained control");
printf("after loop");
}
我的输出是:
footprint=0
the signal catcher never gained control
before loopinside signal catcher!
和应用程序永远保持运行,我需要某种方法来打破这个循环,我使用类似的代码为sybase语句执行超时,因为OCCI不支持超时。
诸如SIGALRM
之类的信号将中断大多数系统调用(但要注意自动重新启动的调用)。您不能依赖它们来中断无系统调用的循环。即使是这样,在收到一个信号后执行也会继续,所以你的代码会愉快地回到循环中。
事实上,你的代码甚至不是有效的c++ (!!!)标准第1.10p24节规定:
实现可以假设任何线程最终都会做一个
- 终止,
- 调用库I/O函数,
- 访问或修改易失性对象,或
- 执行同步操作或一个原子操作。
Alex的while ( footprint == 0 ) ;
建议至少可以纠正这个缺陷。
像while (true);
这样的循环不能被中断,除非终止执行它的线程。必须对循环进行编码,以检查中断条件并退出。
正如Alex在评论中提到的,while ( footprint == 0 ) ;
将正确地实现给定信号处理程序的循环检查。
只是迂腐,footprint
应该声明为sig_atomic_t
而不是int
,但这可能无关紧要。