linux定时器的实现方法

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

时间: 2024-10-18 18:55:54

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

linux获取随机数的方法集合

linux产生随机的方法 取8位数字的方法 [[email protected] scripts]# echo $RANDOM 12465 [[email protected] scripts]# echo $((RANDOM+10000000)) 10023190 [[email protected] scripts]# echo $RANDOM | md5sum | cut -c 1-8 ae74cedb [[email protected] scripts]# uuidgen| md5su

Linux网络性能优化方法简析

Linux网络性能优化方法简析 2010-12-20 10:56 赵军 IBMDW 字号:T | T 性能问题永远是永恒的主题之一,而Linux在网络性能方面的优势则显而易见,这篇文章是对于Linux内核中提升网络性能的一些优化方法的简析,以让我们去后台看看魔术师表演用的盒子,同时也看看内核极客们是怎样灵活的,渐进的去解决这些实际的问题. AD:2014WOT全球软件技术峰会北京站 课程视频发布 对于网络的行为,可以简单划分为 3 条路径:1) 发送路径,2) 转发路径,3) 接收路径,而网络性

linux 安装VMware Tools 方法 (1)

虚拟机安装 VMware Tools for Linux 介绍: VMware Tools是VMware虚拟机中自带的一种增强工具,相当于VirtualBox中的增强功能(Sun VirtualBox Guest Additions),是VMware提供的增强虚拟显卡和硬盘性能.以及同步虚拟机与主机时钟的驱动程序. 只有在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,同时可支持自由拖拽的功能,鼠标也可在虚拟机与主机之前自由移动(不用再按ctrl+alt

linux cat命令使用方法详解--把档案串连接后传到基本输出

linux cat命令使用方法详解--把档案串连接后传到基本输出 日期:2011-12-05 点击:2324 来源: 未知 分享至: 使用方式:cat [-AbeEnstTuv] [--help] [--version] fileName说明:把档案串连接后传到基本输出(萤幕或加 > fileName 到另一个档案)参数:-n 或 --number 由 1 开始对所有输出的行数编号-b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号-s 或 --squeeze-b

Linux修改时间的方法

Linux修改时间的方法 在命令行输入: date 显示当前时间 Fri Aug  3 14:15:16 CST 2007 date '+%x %X' 显示当前时间 2009年08月03日 14时15分00秒 date -s 按字符串方式修改时间 可以只修改日期,不修改时间,输入: date -s 2007-08-03 只修改时间,输入:date -s 14:15:00 同时修改日期时间,注意要加双引号,日期与时间之间有一空格,输入:date -s "2007-08-03 14:15:00&qu

嵌入式linux应用程序调试方法

嵌入式linux应用程序调试方法 四 内存工具 17 4.1 MEMWATCH 17 4.2 YAMD 22 4.3 Electric Fence 24 五 C/C++代码覆盖.性能profiling工具 24 5.1 用gcov来测试代码覆盖率 25 5.2 使用gprof来优化你的C/C++程序 35 四 内存工具 您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形. 许多小组花了许许多多时间来跟踪稀奇古怪的内存错误问题.应用程序在有的开发工作站上能运行,但在新的产品工作站上,这个应用

Linux Telnet 服务开启方法

一.检查是否有telnet chkconfig |grep telnet 二.开启telnet chkconfig telnet on 如果没有安装telnet 下载一个telnet-server.rpm rpm -ivh telnet-server.rpm cat /etc/xinetd.d/telnet chkconfig telnet on 不需要了就关闭 telnet服务 chkconfig telnet off Linux Telnet 服务开启方法,布布扣,bubuko.com

CentOS7 下linux不能上网解决方法?,centos7 eth0 没有ip,IP突然丢失

CentOS7 下linux不能上网解决方法? 在CentOS VMware下安装好linux后,发现有时不能直接联网,特分享下总结出来的经验,希望对新手有用 工具/原料 XP系统 VMware.Workstation.v7.0以上 CentOS-5.5-i386-bin-DVD.iso 其他不同版本应该差不多 方法/步骤 虚拟机安装就不说了,从安装linux后测试发现不能联网,可以先终端重启下网卡 失败如图:   找到点击选择setting   在network Adapter选中,右侧是否是

〖Linux〗PPTP_VPN 搭建方法

PPTP pptp还是比较老牌了,它是基于七层网络模型中的第二层,稳稳的 接下来介绍pptp vpn搭建和连接的方法,一般我使用它是为了打通各个网段(通常是持续集成环境上) 搭建步骤 Server 安装依赖包 依赖很少,就一个pptpd sudo apt-get install pptpd 配置ppp分配的ip地址 sudo vi /etc/pptpd.conf # 修改配置 localip 10.1.0.1 remoteip 10.1.0.100-200 配置帐户密码 sudo vi /etc