note
timerfd对应的时钟到期后,对应内部数据(uint64)计数加1
timerfd支持read方法,poll方法
code
#include <sys/timerfd.h>
#include <poll.h>
#include <thread>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
void timerfd_test1(void)
{
class timer {
public:
struct callback {
void* (*fun)(void*);
void* arg;
};
timer() {
this->fd = -1;
this->cb = nullptr;
}
~timer() {
if (this->fd > 0) {
}
}
int init(long interval) {
int ret = -1;
ret = timerfd_create(CLOCK_REALTIME, 0);
if (ret == -1) {
return -1;
}
this->fd = ret;
this->interval = interval;
return 0;
}
int start(void) {
if (!cb) {
return -1;
}
if (fd < 0) {
return -1;
}
struct itimerspec tim;
struct timespec now;
int ret = -1;
ret = clock_gettime(CLOCK_REALTIME, &now);
if (ret == -1) {
return -1;
}
tim.it_interval.tv_sec = interval;
tim.it_interval.tv_nsec = 0;
tim.it_value.tv_nsec = now.tv_nsec;
tim.it_value.tv_sec = now.tv_sec;
ret = timerfd_settime(this->fd, TFD_TIMER_ABSTIME, &tim, nullptr);
if (ret == -1) {
return -1;
}
this->running = true;
std::thread t(&timer::routine, this, this); // 第一个this因为非静态成员函数做线程,第二个this为参数
t.detach();
return 0;
}
int stop(void) {
running = false;
return 0;
}
int setcb(callback* cbIn) {
if (!cbIn) {
return -1;
}
if (cbIn->fun == nullptr) {
return -1;
}
if (cbIn->arg == nullptr) {
return -1;
}
if (this->cb) {
return -1;
}
this->cb = cbIn;
return 0;
}
protected:
private:
int fd;
long interval;
bool running;
callback* cb;
void routine(void* arg) {
if (arg == nullptr) {
return;
}
timer* me = static_cast<timer*>(arg);
int ret = -1;
struct pollfd fds;
uint64_t cnt = 0;
ssize_t n = 0;
fds.fd = me->fd;
fds.events = POLLIN;
fds.revents = 0;
while (me->running) {
ret = poll(&fds, 1, 0);
if (ret == -1) {
fprintf(stderr, "poll error,%s\n", strerror(errno));
continue;
}
if (ret == 0) {
// fprintf(stdout, "poll return no event\n");
continue;
}
if ((ret == 1) && (fds.revents == POLLIN)) {
// fprintf(stdout, "poll return read event\n");
n = read(fds.fd, &cnt, sizeof(uint64_t));
if (n < 0) {
fprintf(stderr, "read error,%s\n", strerror(errno));
continue;
}
if (n != sizeof(uint64_t)) {
fprintf(stdout, "read return not uint64_t\n");
continue;
}
for (uint64_t i = 0; i < cnt; ++i) {
(me->cb->fun)(me->cb->arg);
}
}
}
}
};
timer t;
timer::callback cb;
auto f = [](void*arg) -> void* {
fprintf(stdout, "%s calleb,arg:%s\n", __FUNCTION__, (char*)arg);
return nullptr;
};
cb.fun = f;
cb.arg = (void*)"hello";
t.setcb(&cb);
t.init(1);
t.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
t.stop();
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
fprintf(stdout, "%s returning...\n", __FUNCTION__);
}
test