当read()时,timerfd神秘地将int设置为0

时间:2018-08-10 09:05:02

标签: unix timer

我正在ubuntu 14.04中创建一个timerfd hello世界,但遇到了一个奇怪的情况:在读取timerfd之后会重置int计数,但不会重置uint64_int。

int main(int agrc, char **argv) {
    unsigned int heartbeat_interval = 1;
    struct itimerspec next_timer;
    struct timespec now;

    if (clock_gettime(CLOCK_REALTIME, &now) == -1)
        err_sys((WHERE + std::string("timer error")).c_str());
    next_timer.it_value.tv_sec = now.tv_sec;
    next_timer.it_value.tv_nsec = 0;
    next_timer.it_interval.tv_sec = heartbeat_interval;
    next_timer.it_interval.tv_nsec = 0;
    int timefd = timerfd_create(CLOCK_REALTIME, 0);
    if (timerfd_settime(timefd, TFD_TIMER_ABSTIME, &next_timer, NULL) == -1) {
        err_sys((WHERE).c_str());
    }
    uint64_t s;
    int exp;
    int count = 1;
    uint64_t count1=0;
    while (1) {
        s = read(timefd, &exp, sizeof(uint64_t));
        if (s != sizeof(uint64_t)) {
            err_sys((WHERE).c_str());
        }
    }
}

1 个答案:

答案 0 :(得分:2)

int exp;
^^^

s = read(timefd, &exp, sizeof(uint64_t));
                  ^^^         ^^^^^^^^

除非您的intuint64_t类型大小相同,否则这是一个非常糟糕的主意。最有可能发生的事情是,您正在读取的64位将覆盖exp ,而堆栈上紧挨着它的其他任何内容。

实际上,即使它们 大小相同,也不是一个好主意。您应该拥有的东西是这样的:

s = read(timefd, &exp, sizeof(exp));

这样,可以保证您永远不会覆盖数据,并且下一行将为您解决问题:

if (s != sizeof(uint64_t)) {

无法解决将无符号整数类型和整数类型区别对待的问题,但是您可以通过为exp使用正确的类型来解决此问题。