检查 time_t 是否为零
Check if time_t is zero
我用 epoll 和 timerfd linux API 写了一个定时器事件循环。 timerfd_gettime
的杂志声明如下:
The it_value field returns the amount of time until the timer will
next expire. If both fields of this structure are zero, then the
timer is currently disarmed.
因此,为了检查计时器当前是处于启用还是解除状态,我编写了以下代码:
bool timer_is_running(struct timer *timer)
{
struct itimerspec timerspec;
if(timerfd_gettime(timer->_timer_fd, &timerspec) == -1) {
printf("[TIMER] Could not get timer '%s' running status\n", timer->name);
return false;
}
printf("[TIMER] Checking running state of timer '%s' it_value.tv_sec = %"PRIu64", it_value.tv_nsec = %"PRIu64"\n", timer->name, (uint64_t) timerspec.it_value.tv_sec, (uint64_t) timerspec.it_value.tv_nsec == 0);
return timerspec.it_value.tv_sec != 0 && timerspec.it_value.tv_nsec != 0;
}
这没有用,所有计时器都被报告为已解除武装。当我查看输出时,我在当前解除武装的计时器上看到以下内容:
[TIMER] Checking running state of timer 'test' it_value.tv_sec = 0, it_value.tv_nsec = 4302591840
经过进一步调查,似乎只有 tv_sec
字段在解除计时器上设置为 0。
这是在 MIPS 架构 (OpenWRT) 的内核 3.18.23 上运行的程序。
在我将此标记为内核实现中的错误之前,我想知道通过执行 time_t == 0
检查 time_t
是否为 0 是否正确。谁能证实这一点?
亲切的问候,
大安
time_t
类型别名是算术或实数类型。算术类型和实数类型都可以隐式地与整数值零进行比较。
此外,在 POSIX 系统上(如 Linux),time_t
被定义为 整数 (参见 this <sys/types.h>
reference ).
虽然 C 标准没有明确指定 time_t
的类型,但出于兼容性原因,几乎所有实现都使用 time_t
的整数。我不知道任何不是整数的实现。
所以你的问题的答案是比较正确。
需要注意的是,只有 tv_sec
成员的类型是 time_t
。 tv_nsec
成员是 long
.
这不是内核实现中的错误。是你的代码有问题。
The it_value field returns the amount of time until the timer will
next expire. If both fields of this structure are zero, then the
timer is currently disarmed.
与此相反的是(假设调用 timerfd_gettime()
成功)如果结构的一个或两个字段不为零,则计时器会启动。
你函数的最后一个return语句是
return timerspec.it_value.tv_sec != 0 && timerspec.it_value.tv_nsec != 0;
which returns true
仅当两个字段都非零时。相反,您需要使用
return timerspec.it_value.tv_sec != 0 || timerspec.it_value.tv_nsec != 0;
我用 epoll 和 timerfd linux API 写了一个定时器事件循环。 timerfd_gettime
的杂志声明如下:
The it_value field returns the amount of time until the timer will
next expire. If both fields of this structure are zero, then the
timer is currently disarmed.
因此,为了检查计时器当前是处于启用还是解除状态,我编写了以下代码:
bool timer_is_running(struct timer *timer)
{
struct itimerspec timerspec;
if(timerfd_gettime(timer->_timer_fd, &timerspec) == -1) {
printf("[TIMER] Could not get timer '%s' running status\n", timer->name);
return false;
}
printf("[TIMER] Checking running state of timer '%s' it_value.tv_sec = %"PRIu64", it_value.tv_nsec = %"PRIu64"\n", timer->name, (uint64_t) timerspec.it_value.tv_sec, (uint64_t) timerspec.it_value.tv_nsec == 0);
return timerspec.it_value.tv_sec != 0 && timerspec.it_value.tv_nsec != 0;
}
这没有用,所有计时器都被报告为已解除武装。当我查看输出时,我在当前解除武装的计时器上看到以下内容:
[TIMER] Checking running state of timer 'test' it_value.tv_sec = 0, it_value.tv_nsec = 4302591840
经过进一步调查,似乎只有 tv_sec
字段在解除计时器上设置为 0。
这是在 MIPS 架构 (OpenWRT) 的内核 3.18.23 上运行的程序。
在我将此标记为内核实现中的错误之前,我想知道通过执行 time_t == 0
检查 time_t
是否为 0 是否正确。谁能证实这一点?
亲切的问候, 大安
time_t
类型别名是算术或实数类型。算术类型和实数类型都可以隐式地与整数值零进行比较。
此外,在 POSIX 系统上(如 Linux),time_t
被定义为 整数 (参见 this <sys/types.h>
reference ).
虽然 C 标准没有明确指定 time_t
的类型,但出于兼容性原因,几乎所有实现都使用 time_t
的整数。我不知道任何不是整数的实现。
所以你的问题的答案是比较正确。
需要注意的是,只有 tv_sec
成员的类型是 time_t
。 tv_nsec
成员是 long
.
这不是内核实现中的错误。是你的代码有问题。
The it_value field returns the amount of time until the timer will next expire. If both fields of this structure are zero, then the timer is currently disarmed.
与此相反的是(假设调用 timerfd_gettime()
成功)如果结构的一个或两个字段不为零,则计时器会启动。
你函数的最后一个return语句是
return timerspec.it_value.tv_sec != 0 && timerspec.it_value.tv_nsec != 0;
which returns true
仅当两个字段都非零时。相反,您需要使用
return timerspec.it_value.tv_sec != 0 || timerspec.it_value.tv_nsec != 0;