Linux定时器接口主要分为三类:

一. sleep(), unsleep, alarm(),引用了SIGALARM信号,在多线程中使用信号又是相当麻烦的。

二. nanosleep(), clock_nanosleep(),让线程挂起,程序失去响应,多线程网络编程中应该避免。

三. timerfd_create(),也是用信号来deliver超时,将时间转变成一个文件描述符,可以像其他I/O事件一样操作定时器,所以程序中在写I/O框架用到定时器首选timerfd_create()。

1. timerfd的创建

int timerfd_create(int clockid, int flags);//成功返回0

第一个参数为CLOCK_REALTIME:表示相对时间,表示从1970.1.1到现在的时间。或者CLOCK_MONOTONIC:表示绝对时间,表示系统重启到现在的时间。

第二个参数为TFD_NONBLOCK(非阻塞)或TFD_CLOEXEC(同O_CLOEXEC)。

2. 定时器的设置(启动和停止定时器)

int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspce *old_value);//成功返回0

第一个参数fd是timerfd_create创建的定时器文件描述符。

第二个参数如果是0表示相对定时器,为TFD_TIMER_ABSTIME表示绝对定时器。

第三个参数new_value设置超时时间,为0表示停止定时器。

第四个参数为原来的超时时间,一般设为NULL。

3. 代码实例:

//代码逻辑:创建timer等待时间,创建timer定时器文件描述符,创建epoll_event事件绑定timer,另起一线程等待事件。时间到,事件触发,操作map之前用mutex锁住,找到GroupID

#include <syso/timerfd.h>

#include <syso/epoll.h>

itimerspec timerValue;
memset(&timerValue, 0, sizeof(timerValue));
timerValue.it_value.tv_sec = tagCollection->GetSampleRate() / 1000;
timerValue.it_value.tv_nsec = (tagCollection->GetSampleRate() % 1000) * 1000 * 1000; // GetPublishInterval is in milliseconds
timerValue.it_interval.tv_sec = timerValue.it_value.tv_sec;
timerValue.it_interval.tv_nsec = timerValue.it_value.tv_nsec;

timerFd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timerFd < 0)
{
  SYSO_CRIT("timer_create failed with error: %s", strerror(errno));
  return;
}
// set events
epoll_event epollEvent;
memset(&epollEvent, 0, sizeof(epoll_event));
epollEvent.events = EPOLLIN;
epollEvent.data.fd = timerFd;
epoll_ctl(epollFd, EPOLL_CTL_ADD, timerFd, &epollEvent); // this is thread safe
// start timer
if (timerfd_settime(timerFd, 0, &timerValue, nullptr) < 0)
{
  SYSO_NOTICE("timerfd_settime failed with error", strerror(errno));
}
else
{
  SYSO_INFO("PlcAdapterProxy Create Get Sample timer: ", timerFd, ", interval: ", timerValue.it_value.tv_sec, " seconds");
}

另起一线程等待epollfd

for(;;) // wait for events
{
  int eventCount = epoll_wait(epollFd, newEvents, MAX_TIMER_EVENTS, -1);
  if (eventCount > 0)
  {
    for (int i = 0; i < eventCount; ++i)
    {
      uint64_t clearEventDummy = 0;
      static_cast<void>(read(newEvents[i].data.fd, &clearEventDummy, sizeof(uint64_t))); // clears the event

      std::unique_lock<std::mutex> lock(epollToTimerIdMapMutex);
      auto iter = epollToTimerIdMap.find(newEvents[i].data.fd);
      if(iter != epollToTimerIdMap.end())
      {
        CollectionTimerElapsed(iter->second);
      }
    }
  }
  else
  {
    SYSO_CRIT("epoll_wait for timers failed, errno:%s", strerror(errno));
  }
}

转载于:https://www.cnblogs.com/embeddedking/p/9689494.html

Linux定时器接口相关推荐

  1. Linux环境SOCKET编程5:定时器接口timerfd

    1.概述 timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景.timerfd是lin ...

  2. Linux定时器:无节拍机制tickless(CONFIG_NO_HZ)

    Linux定时器:无节拍机制tickless(CONFIG_NO_HZ) BAT-Battle 2013-09-01 Tickless 机制是Linux 内核中引入的新定时机制 以前,Linux内核会 ...

  3. Linux定时器和时间管理

    时间管理在内核中占有非常重要的地位.相对于事件驱动而言,内核中有大量的函数都是基于时间驱动的.其中有些函数都是周期执行的,像对调度程序中的运行队列进行平衡调整或对屏幕进行刷新这样的函数,都需要定期执行 ...

  4. linux上的定时器上的jiffies,linux定时器和Jiffies汇.doc

    linux定时器和Jiffies汇 1.linux HZ Linux核心几个重要跟时间有关的名词或变数,将介绍HZ.tick与jiffies. HZ Linux核心每隔固定周期会发出timer int ...

  5. 【Linux 内核 内存管理】内存管理架构 ① ( 内存管理架构组成 | 用户空间 | 内核空间 | MMU 硬件 | Linux 内核架构层次 | Linux 系统调用接口 )

    文章目录 一.内存管理架构组成 ( 用户空间 | 内核空间 | MMU 硬件 ) 二.Linux 内核架构层次 三.Linux 系统调用接口 一.内存管理架构组成 ( 用户空间 | 内核空间 | MM ...

  6. 二十二、linux定时器

    一.Linux 定时器介绍 在 Linux 内核中, 定时器叫做内核定时器, 内核定时器用于控制某个函数, 也就是定时器将要处理的函数在未来的某个特定的时间内执行. 内核定时器注册的处理函数只执行一次 ...

  7. Android 8.0 系统学习(6)---Linux内核接口要求

    接口要求 本页介绍了 Android 正常运行所需的一系列 Linux 内核接口.供应商测试套件 (VTS) 会测试这些接口是否存在以及是否正确无误.这些接口的数量将随时间的推移不断增加,包含越来越多 ...

  8. STM32CubeMX学习笔记(24)——通用定时器接口使用(电容按键检测)

    一.电容按键简介 电容器(简称为电容)就是可以容纳电荷的器件,两个金属块中间隔一层绝缘体就可以构成一个最简单的电容.如图 32-1(俯视图),有两个金属片,之间有一个绝缘介质,这样就构成了一个电容.这 ...

  9. 基于Linux IIO接口的波形采集

    我们在<Linux IIO接口的低成本8通道AD>这篇文章中,已经介绍了如何通过程序对IIO设备进行单次读取,接下来我们就介绍波形的实现,关于IIO子系统的详细说明可以参考资料Linux ...

最新文章

  1. javascript 两个数组组成一个对象
  2. [Java 基础]方法
  3. php mysql 插入多条数据_雷林鹏分享:PHP MySQL 插入多条数据
  4. linux查看redis索引,linux的redis操作命令
  5. python对非it上班族有用吗_非专业人士学Python有用吗?
  6. Java电子书平滑翻页效果_(转载)Android 平滑和立体翻页效果1
  7. bootStrap库介绍
  8. 什么是单镜头反光相机
  9. 计算机视觉基础:图像处理 Task 03 - 颜色空间互转
  10. JavaScript 键盘事件处理
  11. 第三方支付平台-框架介绍
  12. 计算机口语英语对话视频,出国常用英语口语对话视频
  13. 形容java工作者的句子_一些形容工作态度的句子
  14. 打破垄断!国产服务器操作系统正式发布,微软慌了。。
  15. 最新最全论文合集——多模态情感分析
  16. 固态硬盘SSD和机械硬盘哪个好?它们有什么区别?
  17. WhatsApp:硅谷屌丝现世逆袭
  18. 在Arcmap中,如何“让标注和注记的字体,以及符号化后的符号大小随着比例尺大小的变换而变换”???
  19. Dennard scaling(MOSEFT scaling)
  20. PHP信息PHPINFO

热门文章

  1. connect: Address is invalid on local machine or port is not valid on remote
  2. [Objective-c 基础 - 2.5] .h和.m文件,点语法,成员变量作用域
  3. UICamera(NGUI Event system)原理
  4. TortoiseSVN 加锁,服务器地址更换,切换登录用户
  5. css 控制div高度自适应浏览器的高度
  6. JavaScriptjQuery.动态删除元素
  7. 操作数组的常用方式二-----排序、查找
  8. ASP.NET锚标记使用2种小方法
  9. CSS的预编译——less语言基本语法教程(入门)
  10. 用css3和html实现创建 Christmas Tree Ornaments(baubles)