setitimer信号似乎只能在fork之后工作

时间:2014-05-19 01:53:33

标签: c++ linux signals fork posix

我想使用以下C ++代码等待预定义的时间(在此示例中始终为2秒),但仍然可以通过信号中断(这就是我不能使用的原因)睡眠):

#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();
}

我希望这段代码可以打印出#Ho; Hohoho&#34;每2秒钟一次,直到收到SIGUSR1。然后打印&#34;完成测量。&#34;并退出。第二部分按预期工作。但是,我看不到&#34; Hohoho&#34;,所以在我看来,setitimer的SIGALRM不知何故没有收到。奇怪的是,如果我之前做了一个分支,程序按预期工作。更具体地说,如果我在结尾处取消注释两个fork命令中的任何一个,它就可以工作。因此,它不依赖于它是父进程还是子进程,但fork事件在某种程度上很重要。有人可以向我解释发生了什么以及如何修复我的代码吗?

非常感谢, 鲁兹

1 个答案:

答案 0 :(得分:2)

(1)您的setitimer失败,因为您没有正确设置。 Struct 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;