2012-12-26 18 views
0

打破這是我的代碼:使用的sigaction和報警脫離無限循環

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

+0

也許你的意思while(footprint == 0); –

回答

1

信號如SIGALRM會中斷大多數系統調用(但要小心可自動重新啓動的調用)。你不能依靠它們來中斷你的系統調用循環。甚至當它發生時,執行會在信號後恢復,所以你的代碼會很快回到循環。

事實上,你的代碼甚至不是有效的C++(!!!)。該標準的第1.10p24說:

實現可以假定任何線程最終會做一個 如下:

  • 終止,
  • 撥打電話到庫I/O功能
  • 訪問或修改易失性對象,或者
  • 執行同步操作或 原子操作。

while (footprint == 0) ;至少會糾正這個缺陷Alex的建議。

+0

用此pOracleConnStmt-> executeUpdate()替換無限while循環。 –

+0

@ahdy:聽起來它應該至少使用一對庫I/O調用。儘管要小心重啓的系統調用,儘管會有報警信號(你的處理程序將執行),executeUpdate可能會很快恢復到執行它的操作並且不會提前返回。 –

+0

所以我試過:OCIBreak((dvoid *)svchp,(OCIError *)errhp);在捕手方法中,但正如你所說的,它完全忽略了它。使它運行的唯一方法是在終端上手動按下ctrl + c –

1

一個循環如while (true);不能被中斷,除非終止執行它的線程。循環必須進行編碼以檢查中斷情況並退出。

正如亞歷克斯在評論中提到的,while (footprint == 0) ;將正確實現給定信號處理程序的循環檢查。

只是迂腐,footprint應宣佈sig_atomic_t而不是int,但它可能並不重要。