前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux下C++两种常见的定时任务写法

Linux下C++两种常见的定时任务写法

作者头像
CPP开发前沿
发布2024-07-15 15:28:23
1400
发布2024-07-15 15:28:23
举报
文章被收录于专栏:CPP开发前沿

用C++实现一个定时任务框架文章中实现了一个定时任务的框架,本文将将继续针对定时任务进行介绍帮助大家根据具体的应用场景选择合适的方式。

  • epoll_wait

Linux开发环境下们可以将一个基于时间的文件描述符注册到epoll实例,定时器到期时就可以通过epoll接收事件,这种方法在技术事件驱动的应用程序中一种常见的模式,尤其是需要处理多I/O事件的服务程序。如下面的示例:

代码语言:javascript
复制
#define MAX_EVENTS 5

int main() {
    int timer_fd = timerfd_create(CLOCK_REALTIME, 0);
    if (timer_fd == -1) {
        perror("timerfd_create");
        return 1;
    }

    struct itimerspec new_value;
    memset(&new_value, 0, sizeof(new_value));
    
  /* 
    it_value 代表定时器第一次到期的时间。这里设置
    为5秒后,意味着定时器将在5秒后第一次触发
  */
    new_value.it_value.tv_sec = 5;  
    
    /*
    it_interval 设置定时器的重复周期。此处同样设置为每5秒触发一次
    如果设置为0,则定时器只会触发一次
  */
    new_value.it_interval.tv_sec = 5;
    
    if (timerfd_settime(timer_fd, 0, &new_value, NULL) == -1) {
        perror("timerfd_settime");
        return 1;
    }

    int epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        perror("epoll_create1");
        return 1;
    }

    struct epoll_event event;
    memset(&event, 0, sizeof(event));
    
  /*
    EPOLLIN 指定了需要监听的事件类型,此处为“可读”事件,
    对于定时器而言,到期即视为可读
  */
    event.events = EPOLLIN;

  /*
    event.data.fd 设置为 timer_fd,意味着这是我们希望 epoll 
    监视的文件描述符
  */
    event.data.fd = timer_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &event) == -1) {
        perror("epoll_ctl");
        return 1;
    }

    struct epoll_event events[MAX_EVENTS];
    while (1) {
      /*
      epoll_wait 函数等待注册在 epoll 实例 epoll_fd 上的事件,
        这个实例需要事先通过 epoll_create 和 epoll_ctl 配置。
      events 是一个数组,用于接收发生的事件。
      MAX_EVENTS 定义了 events 数组可以接收的最大事件数量。
      -1 表示 epoll_wait 会无限期等待,直到至少有一个事件发生。
    */
        int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        
        for (int i = 0; i < n; i++) {
            if (events[i].data.fd == timer_fd) {
                uint64_t expirations;
                read(timer_fd, &expirations, sizeof(expirations));
                printf("Timer expired %lu times\n", expirations);
            }
        }
    }

    close(timer_fd);
    close(epoll_fd);
    return 0;
}
  • timerfd

Linux环境下,还可以使用timerfd来触发定时任务。timerfd是Linux提供的一个文件描述符,可以用来实现定时任务的触发。如代码所示:

代码语言:javascript
复制
// 获取并打印当前系统时间
void printCurrentTime() {
    time_t now = time(0);
    struct tm tstruct;
    char buf[80];
    tstruct = *localtime(&now);
    strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);

    std::cout << "Current System Time: " << buf << std::endl;
}

int main() {
    // 创建 timerfd
    int timer_fd = timerfd_create(CLOCK_REALTIME, 0);
    if (timer_fd == -1) {
        std::cerr << "Failed to create timerfd: " << strerror(errno) << std::endl;
        return 1;
    }

    // 设置定时器参数
    struct itimerspec timer_spec;
    timer_spec.it_interval.tv_sec = 5; // 每5秒触发一次
    timer_spec.it_interval.tv_nsec = 0;
    timer_spec.it_value.tv_sec = 5; // 初始延迟5秒触发
    timer_spec.it_value.tv_nsec = 0;

    // 启动定时器
    if (timerfd_settime(timer_fd, 0, &timer_spec, NULL) == -1) {
        std::cerr << "Failed to set timerfd: " << strerror(errno) << std::endl;
        close(timer_fd);
        return 1;
    }

    // 读取定时器事件
    uint64_t num_exp;
    ssize_t read_bytes;
    while (true) {
        read_bytes = read(timer_fd, &num_exp, sizeof(num_exp));
        if (read_bytes != sizeof(num_exp)) {
            std::cerr << "Error reading timerfd: " << strerror(errno) << std::endl;
            break;
        }

        // 每次定时器触发时执行的任务
        printCurrentTime();
    }

    // 关闭 timerfd
    close(timer_fd);
    return 0;
}

总结

本文介绍了在Linux下使用C++实现定时任务的两种方法,在实际的开发中大加可以根据实际情况选择合适的实现方式。当然还可以通过std::chrono或者标准的 POSIX 定时器进行实现。具体如何使用大家自行操作,欢迎留言评论。

参考链接: https://blog.csdn.net/weixin_44046545/article/details/138232447

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP开发前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
  • 本文介绍了在Linux下使用C++实现定时任务的两种方法,在实际的开发中大加可以根据实际情况选择合适的实现方式。当然还可以通过std::chrono或者标准的 POSIX 定时器进行实现。具体如何使用大家自行操作,欢迎留言评论。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档