【发布时间】:2020-02-28 19:49:43
【问题描述】:
这是精简后的代码。计时器及时到期(由 epoll_wait 报告),但即使间隔设置为零,epoll_wait 也会持续为计时器 fd 触发准备读取事件 (EPOLLIN)。间隔设置为0,不应该只触发一次吗?
timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
struct itimerspec *my_itimerspec_new, *my_itimerspec_old;
my_itimerspec_new = malloc(sizeof(struct itimerspec));
my_itimerspec_old = malloc(sizeof(struct itimerspec));
bzero(my_itimerspec_new, sizeof(struct itimerspec));
bzero(my_itimerspec_old, sizeof(struct itimerspec));
my_itimerspec_new->it_value.tv_sec = 60;
my_itimerspec_new->it_value.tv_nsec = 0;
my_itimerspec_new->it_interval.tv_sec = 0;
my_itimerspec_new->it_interval.tv_nsec = 0;
my_itimerspec_old->it_value.tv_sec = 0;
my_itimerspec_old->it_value.tv_nsec = 0;
my_itimerspec_old->it_interval.tv_sec = 0;
my_itimerspec_old->it_interval.tv_nsec = 0;
timerfd_settime(timerFd, 0, my_itimerspec_new, my_itimerspec_old);
【问题讨论】:
-
你读过计时器吗?需要minimal reproducible example
-
你为什么使用
malloc?据我所知,没有必要。无论如何,看看 this 部分代码,计时器确实应该只过期一次。所以你应该写一个minimal reproducible example。 -
@hyde 我已经简化了更大应用程序的代码。这里不需要malloc。我发现了问题......正如肖恩指出的那样,我没有阅读计时器。我认为使用 EPOLLET 是不需要的。当然,在生产代码中,我必须阅读并检查触发 Epoll_wait 循环的原因。使用 EPOLLET 和 EPOLLONESHOT 时,是否应该在读取后重新武装直到返回 EAGAIN ,在读取之前还是没有关系?可能这应该是一个新问题。
-
@Shawn 你的问题是正确的!问题已解决。相关问题:在使用EPOLLET和EPOLLONESHOT时,是应该在读取后直到返回EAGAIN,在读取之前再重新装弹还是没关系?
-
@Shawn 如果您发表评论作为答案,我会接受。