linux timerfd_create函数使用介绍

news2024/12/28 4:14:13

timerfd_create 函数简介

timerfd_create 是 Linux 提供的一个系统调用,用于创建一个文件描述符,用来触发定时器事件。可以通过该文件描述符来监视定时器到期事件,例如用 pollselect 进行事件检测。这种机制常用于高效的事件驱动型程序。


函数原型

#include <sys/timerfd.h>

int timerfd_create(int clockid, int flags);
  • clockid: 指定定时器使用的时钟,可以是以下值:
    • CLOCK_REALTIME: 基于系统的实时时钟,受系统时间改变影响。
    • CLOCK_MONOTONIC: 基于系统的单调时钟,不受系统时间改变影响。
  • flags: 指定文件描述符的行为,常用值:
    • 0: 默认行为。
    • TFD_NONBLOCK: 非阻塞模式。
    • TFD_CLOEXEC: exec 时自动关闭文件描述符。

返回值:

  • 成功时返回定时器文件描述符(一个正整数)。
  • 失败时返回 -1,并设置 errno

定时器设置:timerfd_settime

要设置定时器,可以使用以下函数:

#include <sys/timerfd.h>

int timerfd_settime(int fd, int flags, 
                    const struct itimerspec *new_value, 
                    struct itimerspec *old_value);
  • fd: 使用 timerfd_create 创建的文件描述符。
  • flags: 通常为 0。若设置为 TFD_TIMER_ABSTIME,则定时器以绝对时间计算。
  • new_value: 指定定时器的新值,使用 struct itimerspec 结构。
  • old_value: 如果不为 NULL,则保存定时器的旧值。

struct itimerspec 结构:

struct itimerspec {
    struct timespec it_interval; // 定时器的间隔时间
    struct timespec it_value;    // 定时器的初始到期时间
};

示例代码

以下代码展示了如何使用 timerfd_create 创建一个定时器,并通过 poll 等待定时器事件:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <time.h>
#include <stdint.h> // for uint64_t

int main() {
    int timer_fd;
    struct itimerspec new_timer;

    // 创建一个基于单调时钟的定时器
    timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);
    if (timer_fd == -1) {
        perror("timerfd_create failed");
        exit(EXIT_FAILURE);
    }

    // 设置定时器:2秒后触发,然后每隔1秒触发一次
    new_timer.it_value.tv_sec = 2;      // 首次触发的时间(秒)
    new_timer.it_value.tv_nsec = 0;    // 首次触发的时间(纳秒)
    new_timer.it_interval.tv_sec = 1;  // 每次触发的间隔时间(秒)
    new_timer.it_interval.tv_nsec = 0; // 每次触发的间隔时间(纳秒)

    if (timerfd_settime(timer_fd, 0, &new_timer, NULL) == -1) {
        perror("timerfd_settime failed");
        exit(EXIT_FAILURE);
    }

    printf("Timer started! It will fire in 2 seconds, then every 1 second.\n");

    // 使用 poll 监视定时器文件描述符
    struct pollfd poll_fds;
    poll_fds.fd = timer_fd;
    poll_fds.events = POLLIN; // 等待定时器可读事件

    while (1) {
        int ret = poll(&poll_fds, 1, -1); // 无限等待
        if (ret == -1) {
            perror("poll failed");
            exit(EXIT_FAILURE);
        }

        if (poll_fds.revents & POLLIN) {
            uint64_t expirations;
            ssize_t s = read(timer_fd, &expirations, sizeof(expirations));
            if (s != sizeof(expirations)) {
                perror("read failed");
                exit(EXIT_FAILURE);
            }

            printf("Timer expired %llu times\n", (unsigned long long) expirations);
        }
    }

    close(timer_fd);
    return 0;
}

代码说明

  1. 创建定时器:
    • 使用 timerfd_create 创建一个基于 CLOCK_MONOTONIC 的定时器。
  2. 设置定时器:
    • 使用 timerfd_settime 设置首次触发时间为 2 秒,之后每隔 1 秒触发一次。
  3. 等待定时器事件:
    • 使用 poll 等待定时器文件描述符的可读事件。
    • 每当定时器触发,文件描述符变为可读,通过 read 读取定时器触发的次数。
  4. 输出结果:
    • 每次定时器触发时,输出触发的次数。

示例运行

运行上述代码,输出如下:

Timer started! It will fire in 2 seconds, then every 1 second.
Timer expired 1 times
Timer expired 1 times
Timer expired 1 times
...

优点

  • 可以高效地监控多个定时器文件描述符,与 epollpoll 配合使用适合事件驱动编程。
  • 使用单调时钟(CLOCK_MONOTONIC)不受系统时间修改的影响,非常适合定时任务。

注意事项

  • 文件描述符需要在程序结束时关闭(close)。
  • 定时器间隔为 0 时,表示单次触发定时器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2266739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea 8年使用整理

文章目录 前言idea 8年使用整理1. 覆盖application配置2. 启动的时候设置编辑空间大小&#xff0c;并忽略最大空间3. 查询类的关系4. 查看这个方法的引用关系5. 查看方法的调用关系5.1. 查看被调用关系5.2. 查看调用关系 6. 方法分隔线7. 选择快捷键类型8. 代码预览插件9. JReb…

04软件测试需求分析案例-用户登录

通读文档&#xff0c;提取信息&#xff0c;提出问题&#xff0c;整理为需求。 从需求规格说明、设计说明、配置说明等文档获取原始需求&#xff0c;通读原始需求&#xff0c;分析有哪些功能&#xff0c;每种功能要完成什么业务&#xff0c;业务该如何实现&#xff0c;业务逻辑…

【MySQL】踩坑笔记——保存带有换行符等特殊字符的数据,需要进行转义保存

问题描述 从DBeaver中导出了部分业务数据的 insert sql&#xff0c;明明在开发、测试环境都可以一把执行通过&#xff0c;却在预发环境执行前的语法检查失败了&#xff0c;提示有SQL语法错误。 这条SQL长这样&#xff0c;default_sql是要在odps上执行的sql语句&#xff0c;提…

windos挂载目录到linux

验证环境麒麟V10 1: 在windows任意目录设置共享文件夹 2&#xff1a;记住网络路径\LAPTOP-86JV6NT1\gantie13_sdk 在linux中替换为本机ip级相对路径 比如本级ip是192.168.23.23&#xff0c;linux环境需要ping通本地地址 3&#xff1a; sudo apt-get install cifs-utils sud…

springboot494基于java的综合小区管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统综合小区管理系统信息管理难度大&#xff0c;容错率低&am…

数据分析篇001

目录 一、数据是什么&#xff1f; 二、数据能做什么&#xff1f; 三、数据应用四步骤 第一步---搭建数据体系 第二步---积累数据资产 第三步---完成数据分析 第四步---实现数据应用 四、数据的三种性质 变异性 规律性&#xff08;以正态分布为例&#xff09; 客观性…

ModbusTCP从站转Profinet主站案例

一. 案例背景 在复杂的工业自动化场景中&#xff0c;企业常常会采用不同品牌的设备来构建生产系统。西门子SINAMICS G120变频器以其高性能、高精度的速度和转矩控制功能&#xff0c;在电机驱动领域应用广泛。施耐德M580可编程逻辑控制器则以强大的逻辑控制和数据处理能力著称&…

flask后端开发(8):Flask连接MySQL数据库+ORM增删改查

目录 数据库初始化数据库连接创建数据库表添加用户查询用户更新用户删除 在Flask中&#xff0c;很少会使用pymysql直接写原生SQL语句去操作数据库&#xff0c;更多的是通过SQLAichemy提供的ORM技术&#xff0c;类似于操作普通Python对象一样实现数据库的增删改查操作&#xff0…

【社区投稿】自动特征auto trait的扩散规则

自动特征auto trait的扩散规则 公式化地概括&#xff0c;auto trait marker trait derived trait。其中&#xff0c;等号右侧的marker与derived是在Rustonomicon书中的引入的概念&#xff0c;鲜见于Rust References。所以&#xff0c;若略感生僻&#xff0c;不奇怪。 marker …

【Go】context标准库

文章目录 1. 概述1.1 什么是 Context1.2 设计原理1.3 使用场景1.4 Context 分类核心:Context接口2. 源码解读4个实现emptyCtxTODO 和 BackgroundcancelCtxWithCancelcancelCtx.propagateCancel 构建父子关联parentCancelCtx 获取父上下文中的内嵌cancelCtxcanceltimerCtxWithT…

【视觉惯性SLAM:四、相机成像模型】

相机成像模型介绍 相机成像模型是计算机视觉和图像处理中的核心内容&#xff0c;它描述了真实三维世界如何通过相机映射到二维图像平面。相机成像模型通常包括针孔相机的基本成像原理、数学模型&#xff0c;以及在实际应用中如何处理相机的各种畸变现象。 一、针孔相机成像原…

CAPL_构建基于UDS的刷写学习—04 思路的构建_第一部分

前言与导读&#xff1a; 基于前几篇文章我们已经梳理了HEX文件、S19文件的读取和UDS关键的0x34/0x36/0x37等服务的结构。 基于此&#xff0c;我们差不多就完成了前期的知识储备了&#xff0c;那么完成最终的目的——使用capl实现我们还需要解决以下几个问题。 1、文件如何读…

分布式 IO 模块助力冲压机械臂产线实现智能控制

在当今制造业蓬勃发展的浪潮中&#xff0c;冲压机械臂产线的智能化控制已然成为提升生产效率、保障产品质量以及增强企业竞争力的关键所在。而分布式 IO 模块的应用&#xff0c;正如同为这条产线注入了一股强大的智能动力&#xff0c;开启了全新的高效生产篇章。 传统挑战 冲压…

香橙派5Plus启动报错bug: spinlock bad magic on cpu#6, systemd-udevd/443

一、问题 如图&#xff1a; 接上调试串口&#xff0c;每次启动都会报错。不过使用过程中没有发现有什么影响。 百度查阅&#xff0c;有一位博主提到&#xff0c;但是没有细说解决方案&#xff1a; spinlock变量没有初始化_spinlock bad magic on-CSDN博客https://blog.csdn.n…

Matrix-Breakout 2 Morpheus(找到第一个flag)

第一步 信息收集 (1)寻找靶场真实ip arp-scan -l 靶场真实 ip 为192.168.152.154 (2)探测端口及服务 nmap -p- -sV 192.168.52.135 第二步 开始渗透 (1)访问web服务 http://192.168.152.154and http://192.168.52.135:81 发现 81 端口的页面要登录 我们使用 dirb 扫描…

学习C++:关键字

关键字&#xff1a; 作用&#xff1a;关键字是C预先保留的单词&#xff08;标识符&#xff09; 在定义变量或者常量时候&#xff0c;不要用关键字 不要用关键字给变量或者常量起名称

Android笔记(四十):ViewPager2嵌套RecyclerView滑动冲突进一步解决

背景 ViewPager2内嵌套横向滑动的RecyclerView&#xff0c;会有滑动冲突的情况&#xff0c;引入官方提供的NestedScrollableHost类可以解决冲突问题&#xff0c;但是有一些瑕疵&#xff0c;滑动横向RecyclerView到顶部&#xff0c;按住它不放手继续往左拖再往右拖&#xff0c;这…

【提审】Android包提审报权限问题

问题&#xff1a;华为应用市场审核不通过 平台审核检测详情&#xff1a; 日志&#xff1a; 自检工具&#xff1a;frida-server【Unity&Android】安卓app自测应用隐私相关获取和申请权限_apk 隐私合规 自测-CSDN博客 参考资料&#xff1a;Unity启动时获取了android_id等设…

QtQuick之QML应用程序开:一、使用资源文件以及给应用程序添加图标

开发环境: 1、Qt Creator 14.0.1 2、windows10 先看下面的步骤,不明白再返回来看下面官方指导链接。 先看下面的步骤,不明白再返回来看下面官方指导链接。 先看下面的步骤,不明白再返回来看下面官方指导链接。 --------------------------------------------------------…

Task :prepareKotlinBuildScriptModel UP-TO-DATE,编译卡在这里不动或报错

这里写自定义目录标题 原因方案其他思路 原因 一般来说&#xff0c;当编译到这个task之后&#xff0c;后续是要进行一些资源的下载的&#xff0c;如果你卡在这边不动的话&#xff0c;很有可能就是你的IDE目前没有办法进行下载。 方案 开关一下IDE内部的代理&#xff0c;或者…