linux 定时器

linux下软件定时器的实现 可实现Linux下毫秒级的软件定时,但依赖于系统HZ数,如 HZ=100,最小定时为10ms HZ=1000,最小定时才是1ms 理论上可以实现若干个定时器,依赖于系统性能 设计了两种定时方式 STIMER_CYCLE:循环周期定时;STIMER_ONCE:单次定时 立即下载

使用定时器的目的无非是为了周期性的执行某一任务,或者是到了一个指定时间去执行某一个任务。要达到这一目的,一般有两个常见的比较有效的方法。一个是用linux内部的三个定时器,另一个是用sleep, usleep函数让进程睡眠一段时间,使用alarm定时发出一个信号,还有那就是用gettimeofday, difftime等自己来计算时间间隔,然后时间到了就执行某一任务,但是这种方法效率低,所以不常用。

alarm

alarm用在不需要经确定时的时候,返回之前剩余的秒数。

NAME
       alarm - set an alarm clock for delivery of a signal
SYNOPSIS
       #include <unistd.h>
       unsigned int alarm(unsigned int seconds);
DESCRIPTION
       alarm  arranges  for a SIGALRM signal to be delivered to the process in
       seconds seconds.
       If seconds is zero, no new alarm is scheduled.
       In any event any previously set alarm is cancelled.

测试程序:

1   cat timer.c
2  #include <stdio.h>
3  #include <unistd.h>
4  #include <sys/time.h>
5  #include <signal.h>
6   
7  void func()
8  {
9          printf("2 s reached.\n");
10  }
11   
12  int main()
13  {
14          signal(SIGALRM,func);
15          alarm(2);
16          while(1);
17          return 0;
18  }
19   
Linux内置的3个定时器

Linux为每个任务安排了3个内部定时器:

ITIMER_REAL:实时定时器,不管进程在何种模式下运行(甚至在进程被挂起时),它总在计数。定时到达,向进程发送SIGALRM信号。

ITIMER_VIRTUAL:这个不是实时定时器,当进程在用户模式(即程序执行时)计算进程执行的时间。定时到达后向该进程发送SIGVTALRM信号。 

ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计数。定时到达产生SIGPROF信号。ITIMER_PROF记录的时间比ITIMER_VIRTUAL多了进程调度所花的时间。

定时器在初始化是,被赋予一个初始值,随时间递减,递减至0后发出信号,同时恢复初始值。在任务中,我们可以一种或者全部三种定时器,但同一时刻同一类型的定时器只能使用一个。

 

用到的函数有:

#include <sys/time.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, struct itimerval*newvalue, struct itimerval* oldvalue);
strcut timeval
{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
struct itimerval
{
struct timeval it_interval; /*时间间隔*/
struct timeval it_value;   /*当前时间计数*/
};

it_interval用来指定每隔多长时间执行任务, it_value用来保存当前时间离执行任务还有多长时间。比如说, 你指定it_interval为2秒(微秒为0),开始的时候我们把it_value的时间也设定为2秒(微秒为0),当过了一秒, it_value就减少一个为1, 再过1秒,则it_value又减少1,变为0,这个时候发出信号(告诉用户时间到了,可以执行任务了),并且系统自动把it_value的时间重置为it_interval的值,即2秒,再重新计数。

为了帮助你理解这个问题,我们来看一个例子:

1  #include <stdio.h>
2  #include <signal.h>
3  #include <sys/time.h>
4   
5  /*
6  *******************************************************************************************************
7  ** Function name: main()
8  ** Descriptions : Demo for timer.
9  ** Input        : NONE
10  ** Output       : NONE
11  ** Created by   : Chenxibing
12  ** Created Date : 2005-12-29
13  **-----------------------------------------------------------------------------------------------------
14  ** Modified by  :
15  ** Modified Date:
16  **-----------------------------------------------------------------------------------------------------
17  *******************************************************************************************************
18  */
19  int limit = 10;
20  /* signal process */
21  void timeout_info(int signo)
22  {
23      if(limit == 0)
24      {
25          printf("Sorry, time limit reached.\n");
26          return;
27      }
28      printf("only %d senconds left.\n", limit--);
29  }
30   
31  /* init sigaction */
32  void init_sigaction(void)
33  {
34      struct sigaction act;
35   
36      act.sa_handler = timeout_info;
37      act.sa_flags   = 0;
38      sigemptyset(&act.sa_mask);
39      sigaction(SIGPROF, &act, NULL);
40  }
41   
42  /* init */
43  void init_time(void)
44  {
45      struct itimerval val;
46   
47      val.it_value.tv_sec = 1;
48      val.it_value.tv_usec = 0;
49      val.it_interval = val.it_value;
50      setitimer(ITIMER_PROF, &val, NULL);
51  }
52   
53   
54  int main(void)
55  {
56      init_sigaction();
57      init_time();
58      printf("You have only 10 seconds for thinking.\n");
59   
60      while(1);
61     return 0;
62  }
63   

对于ITIMER_VIRTUAL和ITIMER_PROF的使用方法类似,当你在setitimer里面设置的定时器为ITIMER_VIRTUAL的时候,你把sigaction里面的SIGALRM改为SIGVTALARM, 同理,ITIMER_PROF对应SIGPROF。

不过,你可能会注意到,当你用ITIMER_VIRTUAL和ITIMER_PROF的时候,你拿一个秒表,你会发现程序输出字符串的时间间隔会不止2秒,甚至5-6秒才会输出一个,至于为什么,自己好好琢磨一下^_^

sleep

下面我们来看看用sleep以及usleep怎么实现定时执行任务。

  1. #include <signal.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <stdio.h>

  5. static char msg[] = "I received a msg.\n";
  6. int len;
  7. void show_msg(int signo)
  8. {
  9. write(STDERR_FILENO, msg, len);
  10. }
  11. int main()
  12. {
  13. struct sigaction act;
  14. union sigval tsval;

  15. act.sa_handler = show_msg;
  16. act.sa_flags = 0;
  17. sigemptyset(&act.sa_mask);
  18. sigaction(50, &act, NULL);

  19. len = strlen(msg);
  20. while ( 1 )
  21. {
  22. sleep(2); /*睡眠2秒*/
  23. /*向主进程发送信号,实际上是自己给自己发信号*/
  24. sigqueue(getpid(), 50, tsval);
  25. }
  26. return 0;
  27. }

看到了吧,这个要比上面的简单多了,而且你用秒表测一下,时间很准,指定2秒到了就给你输出一个字符串。所以,如果你只做一般的定时,到了时间去执行一个任务,这种方法是最简单的。

时间差

下面我们来看看,通过自己计算时间差的方法来定时:

 

  1. #include <signal.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <time.h>

  6. static char msg[] = "I received a msg.\n";
  7. int len;
  8. static time_t lasttime;
  9. void show_msg(int signo)
  10. {
  11. write(STDERR_FILENO, msg, len);
  12. }
  13. int main()
  14. {
  15. struct sigaction act;
  16. union sigval tsval;

  17. act.sa_handler = show_msg;
  18. act.sa_flags = 0;
  19. sigemptyset(&act.sa_mask);
  20. sigaction(50, &act, NULL);

  21. len = strlen(msg);
  22. time(&lasttime);
  23. while ( 1 )
  24. {
  25. time_t nowtime;
  26. /*获取当前时间*/
  27. time(&nowtime);
  28. /*和上一次的时间做比较,如果大于等于2秒,则立刻发送信号*/
  29. if (nowtime - lasttime >= 2)
  30. {
  31. /*向主进程发送信号,实际上是自己给自己发信号*/
  32. sigqueue(getpid(), 50, tsval);
  33. lasttime = nowtime;
  34. }
  35. }
  36. return 0;
  37. }

这个和上面不同之处在于,是自己手工计算时间差的,如果你想更精确的计算时间差,你可以把 time 函数换成gettimeofday,这个可以精确到微妙。

上面介绍的几种定时方法各有千秋,在计时效率上、方法上和时间的精确度上也各有不同,采用哪种方法,就看你程序的需要。

#1机器学习(西瓜书)自学记录 《机器学习 》 Datawhale 组队学习, 吃瓜自学笔记。 阅读详情

相关推荐

关于三维全波电磁场仿真软件CST的安装和问题解决

百度网盘链接:https://pan.baidu.com/s/1RgWr8Qau1EzSOlh29SewFQ提取码:fzza这里是2023版本的CST,需要其他版本的uu们可以去官网或者其他人的网盘下载。

weixin_60728441的博客 3617

Linux定时器的使用

使用定时器的目的无非是为了周期性的执行某一任务,或者是到了一个指定时间去执行某一个任务。要达到这一目的,一般有两个常见的比较有效的方法。一个是用linux内部的三个定时器,另一个是用sleep, usleep函数让进程睡眠一段时间,使用alarm定时发出一个信号,还有那就是用gettimeofday, difftime等自己来计算时间间隔,然后时间到了就执行某一任务,但是这种方法效率低,所以不常用

星星之火,可以燎原!...... 689

gradle报错:A problem occurred configuring root project ‘My Application‘.

即使翻译了,我开始也看不懂,到处找网上教程,但都是改环境变量。马虎的我即使看了很多遍,改了很多遍也没反应过来,今天第一次搞gradle,突然就报错了,打印出。好了我就继续看项目了。

m0_59878789的博客 4091

linux系统中定时器使用方法,轻松学会Linux定时器的使用方法

我们知道在Linux中有着定时器这一个功能,通过使用定时器我们能够达到周期性的执行某一任务或者是到了一个指定时间去执行某一个任务的效果。对于Liunx初学者来说可能对此不太熟悉怎么运用,为此在本文中课课家笔者就为大家介绍几种Linux定时器的活用方法,让大家在对此有一个基本的了解。要想使用Linux中的定时器功能,我们可以通过三种方法来实现:①利用linux内部的三个定时器②利用sleep, us...

weixin_29483167的博客 2465

告别Nginx原始日志!VictoriaLogs+Grafana构建企业级应用日志分析平台实战

描述:做为一个合格的运维工程师,在面对企业安全运维管理中,日志审计是一项非常重要的工作。授人以鱼不如授人以渔,各位运友们可参照作者的方案设计,在自己的项目中根据实际情况调整落地,例如,不在仅仅采集 NGINX 应用日志,而是采集 Apache、Tomcat、SpringBoot 等多种应用服务器的日志,又如,不再仅仅采集网络设备、安全审计审计日志,而是 Windows、Linux 等多种操作系统的审计日志等,大家可充分发挥想象、实践能力,也欢迎大家在知识星球中分享自己的方案设计,一起交流学习。

全栈工程师修炼指南-IT知识分享 2479

STM32驱动HC-SR04超声波模块:两种精准测距方案详解

本文详解STM32驱动HC-SR04超声波模块的两种精准测距方案:定时器中断计数法和外部中断边沿检测法。涵盖硬件连接、代码实现与优化技巧,帮助开发者根据精度和复杂度需求选择合适方案,提升超声波测距在嵌入式项目中的稳定性和准确性。

g5h6i的博客 685

linux应用定时器的使用

最常用的就是setitimerr和alarm()两个

《愿你归来仍是少年》 516

Open3D (C++) 使用点云创建数字高程模型DEM

Open3D (C++) 使用点云创建数字高程模型DEM

点云侠的博客 1392

Linux应用层的定时器

Linux应用层的定时器 1.定时器理解: 可以将其看作一个闹钟。在Linux应用编程层上,当需要实现下列几种功能时,可考虑使用定时器。 周期性执行某一项任务 在指定时间去执行某一项任务 2.几种定时器介绍 具有定时功能的库函数API接口 1.sleep() 2.usleep() 3.nanosleep() 4.alarm() sleep和usleep,Linux并没有提供系统调用,他们都是在库函数中实现的;是通过...

Wmll1234567的博客 2233

中小企业办公网络配置综合实验华为设备(NAT+策略路由+OSPF+VLAN)

组网需求: 1、PC1、2、3、4均可以访问internet的lo0:8.8.8.8 2、PC1、PC4通过电信ISP访问internet;PC2、PC3通过联通ISP访问internet; 需求分析: 1、internet路由器模拟公网,8.8.8.8模拟公网IP;电信ISP、联通ISP路由器模拟电信和联通运营商;出口路由为企业出口路由器;这四个路由器直连链路之间运行ospf,配置动态路由,实现互通; 2、出口路由与三层交换直连链路运行ospf,动态同步路由信息; 3、出口路由器内网端口配..

A soul tortured by desire 7125

Microsoft AI SDK 与 SAP ABAP:让企业级 AI 能力触手可及的深度整合指南

借助 Microsoft AI SDK,ABAP 开发者无需跳出熟悉的事务码与数据字典,就能把 GPT‑4 的强大语言理解与生成能力深度植入采购、销售、财务等核心业务流程。只要掌握“初始化 SDK → 构造 Prompt → 解析输出”这一范式,未来无论 Azure OpenAI、OpenAI 还是本地化 LLM,都能在同一套代码骨架内快速切换,实现真正的“AI 即服务”。现在,就让我们在下一行 ABAP 里拥抱智能未来。参考链接均于 2025‑07‑22 提取,推荐读者结合实际版本进一步验证。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 435

Linux应用之定时器

Linux 一. 简介 大家都知道,不管定时器还是计数器,在项目开发的过程中是必不可少的。在linux系统当中当然内核有它自己的定时器,在用户模式下也无法使用内核的,今天给大家分享一个我一直用的,真的挺好用。 二.使用 计数器,我们用的最多的就是定义变量自加的方式来计数,但是如果要查看代码的执行时间,或者是到几分钟后退出程序等等,我们就使用下面的方法 1.计时器 #include <stdio.h> #include <sys/time.h> int main() { int t

weixin_45631738的博客 1001

Obsidian与RAG:知识管理的未来之战

摘要: 本文对比了传统RAG、Obsidian和llm-wiki-skill三种知识管理方案。传统RAG依赖查询时临时检索,知识无法积累;Obsidian需人工整理,成本高但结构化强;llm-wiki-skill通过AI在摄入时自动编译知识为结构化Wiki,实现持续增值。核心差异在于知识处理时机——llm-wiki-skill将"查询时检索"转变为"摄入时编译",通过三层Markdown结构(sources/concepts/entities)和自动双向链接构建可进化

ZhangJiqun&191cm&85kg 622

Linux定时器

Linux内核时间管理 系统时间管理需要一个硬件定时器提供时钟 ,通常这个定时器时通用的,有利于系统移植。 像UCOS 或 FreeRTOS 一般使用 Systick 作为系统时钟源(systick 是cortex-m 内核提供的定时器,芯片厂商在使用cortex-m内核制作芯片时为了通用性也会选择它作为芯片的硬件定时器)。 同样Linux 也需要一个定时器来驱动,Linux内核就是使用它来进行一系列的时间管理操作。(具体是什么不深究) Linux 内核中有大量的函数需要时间管理,比如周期性的调度程序、延时

weixin_48006170的博客 9305

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Linux 中的几种定时器

在linux系统中定时器有分为软定时和硬件定时器。硬件定时器一般指的是CPU的一种底层寄存器,它负责按照固定时间频率产生中断信号,形成信号源。基于硬件提供的信号源,系统就可以按照信号中断来计数,计数在固定频率下对应固定的时间,根据预设的时间参数即可产生定时中断信号,这就是软定时。本文主要整理 Linux 系统开发中常使用的软定时器,而硬件定时器涉及到硬件手册这里略过。本文会在持续更新过程中将常用定时器逐一整理出来。alarm当时间到达__seconds秒后,进程会受到一个SIGALRM的信号。

私房菜 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

linux的定时器的使用,linux定时器如何使用方法

Linux提供定时器机制,可以指定在未来的某个时刻发生某个事件,定时器的结构如下:struct timer_list{struct list_head list;unsigned long expires;unsigned long data;void (*function)(unsigned long);};list 实现的时候使用的,和定时器功能无关expires 是定时器定时的滴答数(当前的...

weixin_42298727的博客 2044

linux内核驱动之定时器

linux内核驱动之定时器

wanghongshuai1的博客 1535

linux定时器

linux系统中定时器有很多种,alarm, select, setitimer, timer_create等等,这里只简单的介绍两种定时器,setitimer和timer_create。 1.第一种setitimer函数实现定时器 函数原型如下: /* 参数 which:(可选值如下) ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。 ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。 ITIMER_PROF: 以该进程在用户

weixin_44522306的博客 8134

linux定时器数量限制,linux下如何实现多个定时器

最近在linux下写一个库,是给别人用的,要用到定时器这个功能,而且是多定时器任务的,在windows下实现是很方便的,但是在linux下就遇到了问题,linux下一个进程只能有一个定时器,如果我用了定时器去实现我的任务,那肯定是没问题的,如果用我库的人自己也创建了一个定时器,那么问题就出现了,我的定时器就被覆盖了。我的功能肯定也受到了影响,所以linux下的定时器是需要解决的。没办法,我就自己写...

weixin_42459078的博客 1070

Linux 定时器与延时

软件定时器本质上依赖于硬件定时器中断对系统节拍进行维护并触发软件定时器中断处理,软件定时器中断处理再检查定时器列表中已到期的定时器,执行定时器到期处理函数。具体到Linux内核,硬件定时器中断产生后会更新系统节拍数jiffies/jiffies_64,同时触发软件定时器软中断TIMER_SOFTIRQ,由软中断运行当前处理器上所有到期的定时器处理函数。

weixin_44178960的博客 1422

关于linux下定时器,多定时器

在windows下,我们可以创建多个定时器,而且也可以删除,没个定时器有独立的id号可以区分,但是在linux下一个线程只能有一个定时器,这让我们需要使用多个定时器任务就显得有点尴尬了。但是也不是没有办法。 下面我们来对比windows下的定时器和linux下的定时器任务 MMRESULT timer_handle; 定义一个定时器id; timer_ha

cqltbe131421的博客 1743

linux posix定时器,linux Posix定时器介绍

linux Posix定时器介绍在linux应用编程中,定时器的使用是不可或缺的部分,本文介绍下linux posix定时器常用接口使用方法,如果创建一个有效的定时器。关于函数的使用方法,如果dlinux 服务器装了linux库,直接用man 3 接口查下,以前有相关文章介绍过man 3的使用。1.timer_create clockid :定时间基于哪个时间创建参数含义CLOCK_REALTI...

weixin_42511602的博客 527

linux用户态定时器,linux下精密定时器

在linux下的精密定时器软件定时器的主要功能是实现状态机的超时机制和实现基于超时的计数功能。由于协议状态机运行于Linux内核之上,也就是说在用户态运行。在Linux系统中,用户态应用程序只能调用三个定时器:ITIMER_REAL、 ITIMER_VIRTUAL和ITIMER_PROF。而在协议状态机中需要32个定时器,所以需要新的机制来完成定时功能。软件定时器主要被用来解决硬件定时器的物理限制...

weixin_28978471的博客 610

Linux编程——定时器

定时器是实时应用中非常重要的一个组件,在Linux系统中实际上也提供了丰富的定时器的支持,在Android UWB的底层实现中也被广泛应用,本文将对其进行简单的介绍。

UWB技术博客 1062

linux下取消定时器,linux下setitimer定时器与定时器取消

#include #include #include #include #include #include void timer_thread(union sigval v){static int i = 0;printf ("timer_thread function! %d\n", v.sival_int);printf ("i = %d\n", ++i);}int main(){timer_...

weixin_34269309的博客 1128

linux定时器使用

我们常常有设置系统在某一时间执行相应动作的需求,比如设置电脑什么时候自动锁屏,什么时候自动关机,设置应用程序什么时候自动运行,什么时候自动退出。这些与时间相关的功能,都需要依靠操作系统中的定时器来实现。   linux中定时器的使用原理很简单,你只需设置一个超时时间和相应的执行函数,系统就会在超时的时候执行一开始设置的函数。超时的概念有点模糊,它指的是你设定一个时间,如果当前的时间超过了你设定的时间,那就超时了。比如说,你设置五分钟后系统自动关机,系统会记住五分钟后的具体时间,也就是当前时间再加上五分钟。

自由的天空 2780
上一篇: 简单流媒体服务器开发日记
下一篇: vim 插件
beginning1126
博客等级 码龄14年 102粉丝 94原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值