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