Linux提供定时器机制,可以指定在未来的某个时刻发生某个事件,定时器的结构如下:

struct timer_list
{struct list_head list;unsigned long expires;unsigned long data;void (*function)(unsigned long);
};

list 实现的时候使用的,和定时器功能无关
expires 是定时器定时的滴答数(当前的滴答数为 jiffies )
function 到那个时刻内核调用的函数
data 由于可能多个定时器调用一个函数,为了使得这个函数能够区分不同的定时器,
通过在结构中 data 来标识这个定时器,并且通过调用

function( data )

使得 function 能区分它们,也就是 data 起到 ID 的作用。

如何使用

将定时器加到定时器队列中

void add_timer(struct timer_list *timer)

修改定时器的到期时间

int mod_timer(struct timer_list *timer, unsigned long expires)

将定时器删除(以后这个定时器将不再起作用)

int del_timer(struct timer_list * timer)

如果不要求很精确的话,用 alarm() 和 signal() 就够了
代码:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{printf("alarm!\n");alarm(2);return;
}
int main(void)
{signal(SIGALRM,signalrm_fn);alarm(2);while(1)pause();
}

用select()函数可以实现定时,而且可以将时间精确到毫秒级
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
int count = 0;
void set_timer()
{struct itimerval itv, oldtv;itv.it_interval.tv_sec = 5;itv.it_interval.tv_usec = 0;itv.it_value.tv_sec = 5;itv.it_value.tv_usec = 0;setitimer(ITIMER_REAL, &itv, &oldtv);
}void sigalrm_handler(int sig)
{count++;printf("timer signal.. %d\n", count);
}int main()
{signal(SIGALRM, sigalrm_handler);set_timer();while (count < 1000){}exit(0);
}

利用定时器机制实现多线程编程

为了避免Qt系统中多线程编程带来的问题,还可以使用系统中提供的定时器机制来实现类似的功能。定时器机制将并发的事件串行化,简化了对并发事件的处理,从而避免了thread-safe方面问题的出现。
在下面的例子中,同时有若干个对象需要接收底层发来的消息(可以通过Socket、FIFO等进程间通信机制),而消息是随机收到的,需要有一个GUI主线程专门负责接收消息。当收到消息时主线程初始化相应对象使之开始处理,同时返回,这样主线程就可以始终更新界面显示并接收外界发来的消息,达到同时对多个对象的控制;另一方面,各个对象在处理完消息后需要通知GUI主线程。对于这个问题,可以利用第3节中的用户自定义事件的方法,在主线程中安装一个事件过滤器,来捕捉从各个对象中发来的自定义事件,然后发出信号调用主线程中的一个槽函数。
另外,也可以利用Qt中的定时器机制实现类似的功能,而又不必担心Thread-safe问题。下面就是有关的代码部分:
在用户定义的Server类中创建和启动了定时器,并利用connect函数将定时器超时与读取设备文件数据相关联:
Server:: Server(QWidget *parent) : QWidget(parent)
{
readTimer = new QTimer(this);   //创建并启动定时器connect(readTimer, SIGNAL(timeout()), this, SLOT(slotReadFile()));   //每当定时器超时时调用函数slotReadFile读取文件readTimer->start(100);
}

slotReadFile函数负责在定时器超时时,从文件中读取数据,然后重新启动定时器:
int Server::slotReadFile()    // 消息读取和处理函数
{readTimer->stop();     //暂时停止定时器计时ret = read(file, buf );   //读取文件
if(ret == NULL)
{    readTimer->start(100);     //当没有新消息时,重新启动定时器return(-1);
}else根据buf中的内容将消息分发给各个相应的对象处理……;
readTimer->start(100);    //重新启动定时器
}

  

在该程序中,利用了类似轮循的方式定时对用户指定的设备文件进行读取,根据读到的数据内容将信息发送到各个相应的对象。用户可以在自己的GUI主线程中创建一个Server类,帮助实现底层的消息接收过程,而本身仍然可以处理诸如界面显示的问题。当各个对象完成处理后,通过重新启动定时器继续进行周期性读取底层设备文件的过程。当然,这种方法适合于各对象对事件的处理时间较短,而底层设备发来消息的频率又相对较慢的情况。在这种情况下,上述方法完全可以满足用户的需求,而又避免了处理一些与线程并发有关的复杂问题。

转载于:https://www.cnblogs.com/wuyepeng/p/9788889.html

linux定时器的实现方法相关推荐

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

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

  2. Linux·定时器原理与使用

    目录 定时器的实现原理 内核启动注册时钟中断 内核时钟中断处理流程 内核定时器时间轮算法 定时器的使用方法 一个基于时间轮的定时器简单实现 定时器的实现原理 定时器的实现依赖的是CPU时钟中断,时钟中 ...

  3. linux默认文件大小,Linux 改变文件大小的方法

    函数原型: #include int ftruncate(int fd, off_t length); //改变文件大小为length指定大小;返回值 执行成功则返回0,失败返回-1. 函数ftrun ...

  4. linux 物理内存统计,说说free命令  + Linux可用内存统计方法

    关键在于两个字段,buffers和cached. 你经常会发现Linux系统用了一段时间后,内存所剩无几,free命令,一看,内存全跑到 buffers和cached里面了:这个现象是正常的.访问过的 ...

  5. linux命令在哪里使用,在Linux不同场景中Linux命令的使用方法

    文章目录 1.日志查看实时查看tomcat日志文件查看: 2.修改配置文件内容最常见的就是修改环境变量 3.vi/vim编辑器 4.查看tomcat进程,杀死进程,重启进程. 5.压缩解压缩文件 6. ...

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

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

  7. Linux permission denied解决方法

    Linux permission denied解决方法 参考文章: (1)Linux permission denied解决方法 (2)https://www.cnblogs.com/aarontho ...

  8. [Linux]core文件调试方法

    来源: shaovey的专栏 在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息).使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行 ...

  9. 创建linux目录,Linux目录的创建方法

    创建一个井然有序的目录,可以提高工作效率.现在我们要学习Linux目录的创建方法.那么Linux目录的创建方法是什么呢?今天学习啦小编与大家分享下Linux创建目录的具体操作步骤,有需要的朋友不妨了解 ...

  10. linux下添加自动启动项,linux 开机自动启动脚本方法

    #service servicename status是当前状态 #chkconfig --list servicename是查看启动状态,也就是是否开机自动启动 首先写好脚本,如 mysql,把它放 ...

最新文章

  1. 基于监督学习+自监督学习的智能抠图,精确到发丝 | CVPR 2020
  2. WIN7盗版的警告!你见过吗?
  3. cordova splashscreen插件在android平台的使用
  4. qt服务器获取formdata文件,QT上传(PUT)文件
  5. 汽车软件开发的8种颠覆性趋势及国产自主可控的多领域全数字实时仿真平台SkyEye
  6. 在什么场合里你会用到消息队列?
  7. switch【茶杯头xic】破解xic文件下载
  8. Jeff Dean的传奇人生:超级工程师们拯救谷歌
  9. php 检测域名,PHP实现检测网址是否能够正常打开的方法
  10. 王者无限火力服务器,王者荣耀无限火力
  11. yum install pcre pcre-devel 报错
  12. 实验5-2 符号函数 (10分)
  13. Android设备硬件序列号(SN、串号)分析
  14. Common-pool源码编译——小例子
  15. 什么是“托管代码”?
  16. 人物志 | 知道创宇赵伟:一个核武器的自白
  17. There are multiple heroes that share the same tag within a subtree.
  18. 许可证服务器读取文件时警告错误,在尝试获取许可证时出现无法从许可证服器上读取数据的错误信息...
  19. 基于QFT的量子加法器的原理与实现-mindspore quantum
  20. 自媒体人怎么追实时热点热搜榜?3个免费工具来了

热门文章

  1. 拓端tecdat|时间序列建模三部曲
  2. 服务器2012能安装无线网卡,网件无线网卡在windows 2012支持问题
  3. linux python pymssql,如何在UbuntuLinux上将pymssql安装到Python3.4而不是2.7?
  4. mysql innodb ibd,mysql innodb 从 ibd 文件恢复表数据
  5. 顺序存储循环队列的基本操作
  6. mysql创建定时任务 脚本_linux中定时执行mysql脚本
  7. Learning to Track at 100 FPS with Deep Regression Networks 论文笔记
  8. 卷积神经网络问题总结
  9. .sql文件导入mysql数据库中
  10. Visual Studio 2017 警告C4819解决方案