2014-05-19 29 views
0

我想使用下面的C++代碼等待預定義的時間量(在這個例子中總是2秒),但仍然可以被信號中斷(這就是爲什麼我不' t使用睡眠):setitimer信號似乎只能在分支後工作

#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <sys/types.h> 
#include <sys/time.h> 
#include <signal.h> 
#include <iostream> 

using namespace std; 

int measure() { 
    itimerval  idle; 
    sigset_t  sigset; 
    int    sig; 

    idle.it_value.tv_sec = 2; 
    idle.it_value.tv_usec = 0; 
    setitimer(ITIMER_REAL, &idle, NULL); // TODO: check return value 

    sigemptyset(&sigset); 
    sigaddset(&sigset, SIGALRM); // TODO return values 
    sigaddset(&sigset, SIGUSR1); 

    sigprocmask(SIG_BLOCK, &sigset, NULL); // TODO return value? 
    sigwait(&sigset, &sig); // TODO check return value 
    while(sig != SIGUSR1) { 
    cout << "Hohoho" << endl; 

    idle.it_value.tv_sec = 2; 
    idle.it_value.tv_usec = 0; 
    setitimer(ITIMER_REAL, &idle, NULL); // TODO: check return value 
    sigwait(&sigset, &sig); // TODO check return value 
    } 

    cout << "Done with measurements." << endl; 
    return 0; 
} 

int main(int argc, char **argv) { 
    //if(fork() != 0) exit(0); 
    //if(fork() == 0) exit(0); 
    return measure(); 
} 

我希望此代碼每2秒打印一次「Hohoho」,直到它收到SIGUSR1。然後打印出「完成測量」。並退出。第二部分按預期工作。但是,我沒有看到「Hohoho」,所以在我看來,setitimer的SIGALRM不知何故未收到。奇怪的是,如果我之前做了一個分支,程序按預期工作。更具體地說,如果我在最後取消註釋兩個fork命令中的任何一個,它就可以工作。因此它不依賴於它是父進程還是子進程,但不知何故fork事件很重要。有人可以向我解釋發生了什麼事以及如何解決我的代碼?

非常感謝, 盧茨

回答

2

(1)您setitimer失敗,因爲你沒有正確設置。結構itimerval包含兩個類型爲timeval的結構。您只設置了一個,因此在idle宣佈時拾取本地存儲中的垃圾。

 struct itimerval { 
      struct timeval it_interval; /* next value */ 
      struct timeval it_value; /* current value */ 
     }; 

     struct timeval { 
      time_t  tv_sec;   /* seconds */ 
      suseconds_t tv_usec;  /* microseconds */ 
     }; 

如果您想要每2秒鐘重複計時器,則將第二組設置爲使用相同的值重複。

idle.it_value.tv_sec = 2; 
    idle.it_value.tv_usec = 0; 
    idle.it_interval.tv_sec = 2; 
    idle.it_interval.tv_usec = 0; 
+0

謝謝,鴨。在我真實的代碼中,我不想一次又一次地設置相同的時間,但確定報警後的下一個時間間隔。所以我應該將it_interval設置爲0,然後像上面的代碼中那樣顯式重置計時器。我首先犯了一個錯誤,但最終修復了它。再次感謝。 – PowerGnom

相關問題