linux应用编程:采用timerfd的方式设置定时器,配合epoll高效执行相应的功能接口

7 篇文章 0 订阅
1 篇文章 0 订阅
/********************************************************
* Filename: timerfd.c
* Desprition: a sample program of timerfd
* Date: 2019-12-10
********************************************************/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>

#if 0
struct timespec {
    time_t tv_sec;                /* Seconds */
    long   tv_nsec;               /* Nanoseconds */
};

struct itimerspec {
    struct timespec it_interval;  /* Interval for periodic timer */
    struct timespec it_value;     /* Initial expiration */
};
#endif

#define EPOLL_LISTEN_CNT        256
#define EPOLL_LISTEN_TIMEOUT    500

#define LOG_DEBUG_ON 1

#ifdef LOG_DEBUG_ON 
#define LOG_DEBUG(fmt, args...) \
    do {  \
        printf("[DEBUG]:");\
        printf(fmt "\n", ##args); \
    } while(0);
#define LOG_INFO(fmt, args...) \
    do { \
        printf("[INFO]:");\
        printf(fmt "\n", ##args); \
    } while(0);
#define LOG_WARNING(fmt, args...) \
    do { \
        printf("[WARNING]:");\
        printf(fmt "\n", ##args); \
    } while(0);
#else
#define LOG_DEBUG(fmt, args...) 
#define LOG_INFO(fmt, args...) 
#define LOG_WARNING(fmt, args...) 
#endif
#define LOG_ERROR(fmt, args...) \
    do{ \
        printf("[ERROR]:");\
        printf(fmt "\n", ##args);\
    }while(0);

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

static int g_epollfd[3];
static int g_timerfd[3];
uint64_t tot_exp = 0;

static void help(void)
{
    exit(0);
}

static void print_elapsed_time(void)
{
    static struct timespec start;
    struct timespec curr;
    static int first_call = 1;
    int secs, nsecs;
    
    if (first_call) {
        first_call = 0;
        if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) 
            handle_error("clock_gettime");
    }   
    
    if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) 
        handle_error("clock_gettime");
    
    secs = curr.tv_sec - start.tv_sec;
    nsecs = curr.tv_nsec - start.tv_nsec;
    if (nsecs < 0) {
        secs--;
        nsecs += 1000000000;
    }   
    printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
}

void timerfd_handler(int fd)
{
    uint64_t exp = 0;
    
    read(fd, &exp, sizeof(uint64_t)); 
    tot_exp += exp;
    print_elapsed_time();
    printf("read: %llu, total: %llu\n", (unsigned long long)exp, (unsigned long long)tot_exp);

    return;
}

void timerfd_handler2(int fd)
{
    uint64_t exp = 0;
    
    read(fd, &exp, sizeof(uint64_t)); 
    tot_exp += exp;
    print_elapsed_time();
    printf("**************read: %llu, total: %llu\n", (unsigned long long)exp, (unsigned long long)tot_exp);

    return;
}

void timerfd_handler3(int fd)
{
    uint64_t exp = 0;
    
    read(fd, &exp, sizeof(uint64_t)); 
    tot_exp += exp;
    print_elapsed_time();
    printf("++++++++++++++read: %llu, total: %llu\n", (unsigned long long)exp, (unsigned long long)tot_exp);

    return;
}

void epoll_event_handle(void)
{
    int i = 0;
    int fd_cnt = 0;
    int sfd;
    struct epoll_event events[EPOLL_LISTEN_CNT];    

    memset(events, 0, sizeof(events));
    while(1) 
    {   
        /* wait epoll event */
        fd_cnt = epoll_wait(g_epollfd, events, EPOLL_LISTEN_CNT, EPOLL_LISTEN_TIMEOUT); 
        for(i = 0; i < fd_cnt; i++) 
        {   
            sfd = events[i].data.fd;
            if(events[i].events & EPOLLIN) 
            {   
				if(sfd == g_timerfd[0])
				{
                    timerfd_handler(sfd);
				}
				if(sfd == g_timerfd[1])
				{
					timerfd_handler2(sfd);
				}
				if(sfd == g_timerfd[2])
				{
					timerfd_handler3(sfd);
				}   
            }   
        } 
    }   
}

int epoll_add_fd(int fd,int *g_epollfd)
{
    int ret;
    struct epoll_event event;

    memset(&event, 0, sizeof(event));
    event.data.fd = fd;
    event.events = EPOLLIN | EPOLLET;

    ret = epoll_ctl(*g_epollfd, EPOLL_CTL_ADD, fd, &event);
	
    if(ret < 0) {
        LOG_ERROR("epoll_ctl Add fd:%d error, Error:[%d:%s]", fd, errno, strerror(errno));
        return -1;
    }

    LOG_DEBUG("epoll add fd:%d--->%d success", fd, *g_epollfd);
    return 0;    
}

int epollfd_init(int *g_epollfd)
{
    int epfd;

    /* create epoll fd */
    epfd = epoll_create(EPOLL_LISTEN_CNT); 
    if (epfd < 0) {
        LOG_ERROR("epoll_create error, Error:[%d:%s]", errno, strerror(errno));
        return -1;
    }
    *g_epollfd = epfd;
    LOG_DEBUG("epoll fd:%d create success", epfd);

    return epfd;
}

int timerfd_init(int sec,int *g_timerfd,int *g_epollfd)
{
	int tmfd;
    int ret;
    struct itimerspec new_value;

    new_value.it_value.tv_sec = sec;
    new_value.it_value.tv_nsec = 0;
    new_value.it_interval.tv_sec = sec;
    new_value.it_interval.tv_nsec = 0;
    
    tmfd = timerfd_create(CLOCK_MONOTONIC, 0);
    if (tmfd < 0) {
        LOG_ERROR("timerfd_create error, Error:[%d:%s]", errno, strerror(errno));
        return -1;
    }

    ret = timerfd_settime(tmfd, 0, &new_value, NULL);
    if (ret < 0) {
        LOG_ERROR("timerfd_settime error, Error:[%d:%s]", errno, strerror(errno));
        close(tmfd);
        return -1;
    }
 
    if (epoll_add_fd(tmfd,g_epollfd)) {
        close(tmfd);
        return -1;
    }
    *g_timerfd = tmfd;
	printf("\ntmfd is %d\n",tmfd);

    return 0;
}

int main(int argc, char **argv)
{
	int i = 0;
	memset(g_epollfd, -1, sizeof(g_epollfd));
	memset(g_timerfd, -1, sizeof(g_timerfd));
	
	for(i=0;i<10;i++)
	{
		if (epollfd_init(&g_epollfd[i]) < 0) {
			return -1;
		}
	}

	for(i=0;i<3;i++)
	{
		if (timerfd_init(i+2,&g_timerfd[i],&g_epollfd[i])) {
			return -1;
		}
	}

    /* event handle */
    epoll_event_handle();

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值