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类,帮助实现底层的消息接收过程,而本身仍然可以处理诸如界面显示的问题。当各个对象完成处理后,通过重新启动定时器继续进行周期性读取底层设备文件的过程。当然,这种方法适合于各对象对事件的处理时间较短,而底层设备发来消息的频率又相对较慢的情况。在这种情况下,上述方法完全可以满足用户的需求,而又避免了处理一些与线程并发有关的复杂问题。

linux定时器的实现方法的更多相关文章

  1. Linux 定时器应用【转】

    Linux 定时器应用 实验目的 阅读 Linux 相关源代码,学习 Linux 系统中的时钟和定时器原理,即,ITIMER_REAL实时计数,ITIMER_VIRTUAL 统计进程在用户模式执行的时 ...

  2. 嵌入式linux应用程序移植方法总结

    嵌入式linux应用程序移植方法总结 前段时间一直在做openCapwap的移植和调试工作,现在工作已接近尾声,编写本文档对前段工作进行一个总结,分享下openCapwap移植过程中的经验和感悟.江浩 ...

  3. 1008win7与虚拟机中的linux共享文件的(详细)方法

    转自http://jingyan.baidu.com/article/ca00d56c74dde4e99eebcfd2.html 好东西一起分享 win7与虚拟机中的linux共享文件的(详细)方法 ...

  4. 修改linux系统时间的方法(date命令)

    修改linux系统时间的方法(date命令) 来源:互联网 作者:佚名 时间:11-18 23:22:27 [大 中 小] date命令不仅可以显示系统当前时间,还可以用它来修改系统时间,下面简单的介 ...

  5. Linux下软件安装方法即路径设置

    Linux下软件安装方法即路径设置 http://www.cnblogs.com/edward259/archive/2010/07/02/1770066.html

  6. 截取linux文件存储路径方法

    1.截取linux文件存储路径方法 package com.tydic.eshop.action.freemarker; public class dddd { public static void ...

  7. linux php安装扩展方法 查找配置文件

    如何在linux中查看nginx.apache.php.mysql配置文件路径了,如果你接收一个别人配置过的环境,但没留下相关文档.这时该怎么判断找到正确的加载文件路径了.可以通过以下来判断 1.判断 ...

  8. linux定时器用法

    linux定时器  原文出自http://www.cnblogs.com/processakai/archive/2012/04/11/2442294.html 今天看书看到了关于alarm的一些用法 ...

  9. Linux 常用命令使用方法大搜刮

    Linux 常用命令使用方法大搜刮 1.# 表示权限用户(如:root),$ 表示普通用户  开机提示:Login:输入用户名  password:输入口令   用户是系统注册用户成功登陆后,可以进入 ...

随机推荐

  1. 修!咻咻!团队Beta作业博客汇总

    作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Beta冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 队 ...

  2. Windows安装Nginx需要注意的地方

      在使用 Nginx 之前,首先要三连问,它是什么?用来做什么?为什么用它? 这篇文章很好的解答了上面的问题,并补充了什么是正向代理和反向代理以及区别的知识 https://www.cnblogs. ...

  3. sublime-text-3-build-3207 破解+注册码

    按照以下步骤依次进行 打开 https://hexed.it/ 单机 "Open file" 并选择 "sublime_text.exe" 可执行文件. 转到 ...

  4. WPF 精修篇 多属性触发器

    原文:WPF 精修篇 多属性触发器 多属性触发器就是多个属性都满足在触发 在属性触发器上加了一些逻辑判断 举栗子 这个栗子里  textBox 要满足俩个条件 才能触发背景变色 1)textbox的 ...

  5. C# do...while循环

    一.简介 在for和while的循环是在头部写测试循环条件,而do....while的循环是在循环的尾部写测试条件 do...while的循环和while的类似,但是do...while的最少执行一次 ...

  6. HeadFirst设计模式(一)策略者模式

    最近在看HeadFirst设计模式一书,作为一个半路出家的程序员,感觉很多东西需要学习,学习的路程中有些东西学了当时觉得理解了,但日常工作中没有使用到渐渐的自己就忘记了.--------------- ...

  7. elementUI,设置日期,只能选择今天和今天以后的, :picker-options="pickerOptions"

    1. html 加 :picker-options="pickerOptions" <el-date-picker v-model="shop.receive_ti ...

  8. HubSpot company数据在UI上的展示和通过API方式进行获取

    在网页查看所有的company: https://app.hubspot.com/contacts/6798828/companies/list/view/all/? 打开第一个名为SAP的compa ...

  9. MySql定时备份脚本

    最近需要对某服务的数据库数据进行备份,因此参考网上教程完成数据库备份脚本. 因为服务的使用频率较低,因此设置定时任务,在每天的中午以及午夜时分进行备份操作. #!/bin/bash # 设置mysql ...

  10. Bash Shell如何实现动态变量

    有时需要遍历所有变量,但是如何生成变量名之后,再取到变量名里的值呢? 具体方法 测试动态变量的脚本: #!/bin/bash a=1 b=abc abc1='12345abc' tmp1=$(eval ...