使用sigaction和alarm来打破无限循环

时间:2012-12-26 15:33:45

标签: c++

这是我的代码:

#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=%d\n", 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不支持超时。

2 个答案:

答案 0 :(得分:1)

除了终止执行它的线程之外,不能中断诸如while (true);之类的循环。必须对循环进行编码以检查中断条件并退出。

正如Alex在评论中提到的,while ( footprint == 0 ) ;将正确地实现对给定信号处理程序的循环检查。

只是迂腐,footprint应该被宣布为sig_atomic_t而不是int,但这可能并不重要。

答案 1 :(得分:1)

SIGALRM等信号会中断大多数系统调用(但要注意自动重启的调用)。你不能依赖它们来中断你的系统调用循环。即使它发生了,执行也会在信号之后重新开始,因此您的代码会很快回到循环状态。

实际上,您的代码甚至不是有效的C ++(!!!)。标准第1.10p24节说:

  

实现可以假设任何线程最终都会执行一个   以下内容:

     
      
  • 终止,
  •   
  • 调用库I / O函数,
  •   
  • 访问或修改易失性对象,或
  •   
  • 执行同步操作或   原子操作。
  •   

Alex对while ( footprint == 0 ) ;的建议至少会纠正这个缺陷。