使用信号和报警来打破无限循环

  • 本文关键字:无限循环 信号 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=%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,但这可能无关紧要。

最新更新