bud*_*888 3 c linux timer polling
我正在使用timerfd 实现一个计时器。这是一个相对计时器,我只需要按照设置的速率永远重复。我想对这个事件进行轮询,最初尝试使用轮询。当我这样做时,我会第一次看到计时器事件,然后就再也看不到了。但是,当我更改为使用 epoll(timerfd 的设置方式完全没有改变)时,它按预期工作。
这是带有轮询的代码:
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
int main(int ac, char *av[])
{
struct pollfd p;
int timerfd;
struct itimerspec timerValue;
/* clear pollfd */
bzero(&p, sizeof(p));
/* set timerfd */
timerfd = timerfd_create(CLOCK_REALTIME, 0);
if (timerfd < 0) {
printf("failed to create timer fd\n");
exit(1);
}
bzero(&timerValue, sizeof(timerValue));
timerValue.it_value.tv_sec = 1;
timerValue.it_value.tv_nsec = 0;
timerValue.it_interval.tv_sec = 1;
timerValue.it_interval.tv_nsec = 0;
/* set events */
p.fd = timerfd;
p.revents = 0;
p.events = POLLIN;
/* start timer */
if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
printf("could not start timer\n");
exit(1);
}
/* wait for events */
while (1) {
int numEvents = poll(&p, 1, -1);
if (numEvents > 0) {
int timersElapsed = 0;
(void) read(p.fd, &timersElapsed, 8);
printf("timers elapsed: %d\n", timersElapsed);
}
}
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
这是 epoll 的代码:
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
int main(int ac, char *av[])
{
struct epoll_event epollEvent;
struct epoll_event newEvents;
int timerfd;
int epollfd;
struct itimerspec timerValue;
/* set timerfd */
timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timerfd < 0) {
printf("failed to create timer fd\n");
exit(1);
}
bzero(&timerValue, sizeof(timerValue));
timerValue.it_value.tv_sec = 1;
timerValue.it_value.tv_nsec = 0;
timerValue.it_interval.tv_sec = 1;
timerValue.it_interval.tv_nsec = 0;
/* set events */
epollfd = epoll_create1(0);
epollEvent.events = EPOLLIN;
epollEvent.data.fd = timerfd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &epollEvent);
/* start timer */
if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
printf("could not start timer\n");
exit(1);
}
/* wait for events */
while (1) {
int numEvents = epoll_wait(epollfd, &newEvents, 1, 0);
if (numEvents > 0) {
int timersElapsed = 0;
(void) read(epollEvent.data.fd, &timersElapsed, 8);
printf("timers elapsed: %d\n", timersElapsed);
}
}
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
知道我在民意调查中可能做错了什么吗?也许它不适合与timerfd一起使用?谢谢。
小智 5
好吧,这是一个老问题,但无论如何。问题出在这几行代码上:
int timersElapsed = 0;
(void) read(p.fd, &timersElapsed, 8);
printf("timers elapsed: %d\n", timersElapsed);
Run Code Online (Sandbox Code Playgroud)
int timersElapsed是4个字节。读取 8 个字节会导致堆栈溢出,从而产生不可预测的行为。
更改timersElapsed为 along int并修复 printf 对我来说很有效。
long int timersElapsed = 0;
(void) read(p.fd, &timersElapsed, 8);
printf("timers elapsed: %ld\n", timersElapsed);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5106 次 |
| 最近记录: |