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!

OCCI はタイムアウトをサポートしていないため、同様のコードを使用して sybase ステートメントの実行をタイムアウトにしています。

4

2 に答える 2

1

などのシグナルは、SIGALRMほとんどのシステム コールを中断します (ただし、自動的に再開可能なコールには注意してください)。システムコールのないループを中断するためにそれらに頼ることはできません。その場合でも、シグナルの後で実行が再開されるため、コードはすぐにループに戻ります。

実際、あなたのコードは有効な C++ でさえありません (!!!)。標準のセクション 1.10p24 には次のように記載されています。

実装では、スレッドが最終的に次のいずれかを実行すると想定する場合があります。

  • 終了し、
  • ライブラリ I/O 関数を呼び出します。
  • 揮発性オブジェクトへのアクセスまたは変更、または
  • 同期操作またはアトミック操作を実行します。

アレックスの提案はwhile ( footprint == 0 ) ;、少なくともこの欠陥を修正します。

于 2012-12-26T16:40:18.610 に答える
1

などのループはwhile (true);、それを実行しているスレッドを終了しない限り、中断できません。ループは、割り込み条件をチェックして終了するようにコーディングする必要があります。

Alex がコメントで述べたようにwhile ( footprint == 0 ) ;、特定のシグナル ハンドラのループ チェックを正しく実装します。

衒学的なだけで、notfootprintと宣言する必要がありますが、おそらく問題ではありません。sig_atomic_tint

于 2012-12-26T16:16:11.047 に答える