0

这是我的代码:

#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 不支持超时。

4

2 回答 2

1

一个循环while (true);不能被中断,除非终止执行它的线程。必须对循环进行编码以检查中断条件并退出。

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

只是迂腐,footprint应该声明sig_atomic_tnot int,但这可能无关紧要。

于 2012-12-26T16:16:11.047 回答
1

诸如SIGALRM会中断大多数系统调用的信号(但要注意自动重启的调用)。您不能依赖它们来中断您的无系统调用循环。即使它这样做了,执行也会在一个信号之后恢复,所以你的代码很高兴地回到了循环。

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

实现可能假设任何线程最终都会执行以下操作之一:

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

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

于 2012-12-26T16:40:18.610 回答