更好的计时器类实现:LINUX RTC机制实现计时器类(原创)

很多时候需要在LINUX下用到定时器,但像setitimer()和alarm()这样的定时器有时会和sleep()函数发生冲突,这样就给编程带来了很大的困难。
    写了一个定时器的类,使用select进行精确定时。而且可以在系统中创建不限数量的定时器,且互不干扰。类的内部采用线程实现。即线程+select。代码如下:

CTimer.h:
/*
* CTimer.h
*
* Created on: 2009-7-13
*      Author: DEAN
*/

//////////////////////////////////////////////////////////////////////////
// This class provide a timer to finish some works.
// Call SetTimer() to set the timer_interval. Call StartTimer()
// to enable it and call StopTimer() to stop it.
// The work you want to do should be written on OnTimer
// function.
//////////////////////////////////////////////////////////////////////////

#ifndef CTIMER_H_
#define CTIMER_H_

#include <pthread.h>
#include <sys/time.h>

class CTimer
{
private:
    pthread_t thread_timer;
    long m_second, m_microsecond;
    static void *OnTimer_stub(void *p)
    {
        (static_cast<CTimer*>(p))->thread_proc();
    }
    void thread_proc();
    void OnTimer();
public:
    CTimer();
    CTimer(long second, long microsecond);
    virtual ~CTimer();
    void SetTimer(long second,long microsecond);
    void StartTimer();
    void StopTimer();
};
#endif /* CTIMER_H_ */

CTimer.cpp:
/*
* CTimer.cpp
*
* Created on: 2009-7-13
*      Author: DEAN
*/

#include "CTimer.h"
#include <iostream>
#include <sys/select.h>
#include <time.h>
#include <pthread.h>

using namespace std;
//////////////////////////public methods//////////////////////////
CTimer::CTimer():
    m_second(0), m_microsecond(0)
{
}

CTimer::CTimer(long second, long microsecond) :
    m_second(second), m_microsecond(microsecond)
{
}

CTimer::~CTimer()
{
}

void CTimer::SetTimer(long second, long microsecond)
{
    m_second = second;
    m_microsecond = microsecond;
}

void CTimer::StartTimer()
{
    pthread_create(&thread_timer, NULL, OnTimer_stub, this);
}

void CTimer::StopTimer()
{
    pthread_cancel(thread_timer);
    pthread_join(thread_timer, NULL); //wait the thread stopped
}

//////////////////////////private methods//////////////////////////
void CTimer::thread_proc()
{
    while (true)
    {
        OnTimer();
        pthread_testcancel();
        struct timeval tempval;
        tempval.tv_sec = m_second;
        tempval.tv_usec = m_microsecond;
        select(0, NULL, NULL, NULL, &tempval);
    }
}

void CTimer::OnTimer()
{
    cout<<"Timer once..."<<endl;
}

示例代码main.cpp:
/*
* main.cpp
*
* Created on: 2009-7-19
*      Author: DEAN
*/

#include <iostream>
#include "CTimer.h"

using namespace std;

int main()
{
    CTimer t1(1,0),t2(1,0);    //构造函数,设两个定时器,以1秒为触发时间。参数1是秒,参数2是微秒。
    t1.StartTimer();
    t2.StartTimer();
    sleep(10);
    return 0;
}

使用的话其实很简单,只要写一下OnTimer()函数的内容就行了,定时器会在每个定时器触发时调用此函数。里面用到的一个点是使用类的成员函数作为线程体的执行函数,需要进行一下静态类型转换。在上面已标出:
    static void *OnTimer_stub(void *p)
    {
        (static_cast<CTimer*>(p))->thread_proc();
    }
    有了这个类以后,使用定时器就方便多了:-)

///LINUX RTC机制实现计时器类(原创) ///////////

在LINUX中经常要使用计时器,而在LINUX环境下使用计时器不像WINDOWS环境下那样一个SETTIMER()方便,主要有三种方式:使用SLEEP/USLEEP+单独线程;SETITMER加处理信号SIGALRM,或者是RTC机制。这里我讲到的是使用RTC机制实现计时器类。这种方法最为优越,它与传统意义上的SLEEP和SIGALRM信号是分离的,它的运行不受SLEEP的影响,而像SETITMER等都会受到SLEEP的影响,因为它们使用的是同一时钟。
    以前用select实现的计时器类(http://hi.baidu.com/susdisk/blog/item/03f70d35e8e2e182a61e1288.html)其实并不是真正的计时器,它是一个循环,只是在处理完一次ONTIMER()事件后停下了一秒,然后再接着一次ONTIMER(),这其实并不是真正的计时器。真正的计时器应该是不管是否在处理ONTIMER()事件,它都会触发。
    RTC(real-time clock)。现在可以使用LINUX下的RTC机制来编写计时器类,这个类是完全意义上的计时器,经过测试,也基本不占用cpu时间,因为它采用的是底层的硬件时钟,rtc的文档中说的很明白,它与系统时钟最大的区别在于即使它在机器耗能非常低的情况下,也会触发此时钟信号。它也与SLEEP、SETITIMER等函数是完全独立的,就是说,使用这个计时器类,你依然可以使用各种SLEEP函数等,互不影响,这一点我觉得是最重要的。

Linux下的定时器类实现(select定时+线程)的更多相关文章

  1. Linux下的定时器:alarm()与setitimer()

    Linux下的定时器有两种,以下分别介绍: 1.alarm 如果不要求很精确的话,用alarm()和signal()就够了 unsigned int alarm(unsigned int second ...

  2. linux 下 用phpmailer类smtp发送邮件始终不成功,提示:ERROR: Failed to co

    https://zhidao.baidu.com/question/509191264.html?fr=iks&word=PHPMailerSMTP+connect()+failed& ...

  3. Linux下的定时器

    以下摘自linux下的man文件:(man  getitimer) #include  <sys/time.h> int  getitimer(int which,  struct iti ...

  4. Linux下实现C++类的动态链接

    1. 背景 在java中,jvm支持类的动态链接(Class.forName(String className)),用起来也很方便.动态链接是实现IOC(Inversion of Control,控制 ...

  5. Linux下如何查看高CPU占用率线程

    转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...

  6. Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算

    目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps ...

  7. (笔记)Linux下如何查看高CPU占用率线程

    在 Linux 下 top 工具可以显示 cpu 的平均利用率(user,nice,system,idle,iowait,irq,softirq,etc.),可以显示每个 cpu 的利用率.但是无法显 ...

  8. (转)linux下进程的进程最大数、最大线程数、进程打开的文件数和ulimit命令修改硬件资源限制

    ulimit命令查看和更改系统限制 ulimit命令详解 ulimit用于shell启动进程所占用的资源,可以用来设置系统的限制 语法格式 ulimit [-acdfHlmnpsStvw] [size ...

  9. Linux下如何查看高CPU占用率线程 专题

    Java 系统性能分析 命令 1. cpu分析 top , pidstat(sysstat) pid -p PID -t 1 10 vmstat 1 CPU上下文切换.运行队列.利用率 ps Hh - ...

随机推荐

  1. J-query extend()方法

    1.如果没有冲突参数会弥在后面. 2.参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值.

  2. GeForce Experience关闭自动更新

    GeForce Experience驱动更新很烦,而且有时更新后就打不开了,找到种方法关闭更新 1.安装并登陆 2.打开 C:\ProgramData\NVIDIA Corporation 3.进入D ...

  3. C_数据结构_递归实现求阶乘

    # include <stdio.h> int main(void) { int val; printf("请输入一个数字:"); printf("val = ...

  4. oracle加注释

    COMMENT ON table GC_G_DOC84 IS '行政处罚撤销决定书'; COMMENT ON column GC_G_DOC84.CASEID IS '案件记录ID';

  5. Beta 冲刺 随笔合集

    团队展示: Team一二一 Beta 冲刺 凡事预则立 Beta冲刺 一 Beta冲刺 二 Beta冲刺 三 Beta冲刺 四 Beta冲刺 五 Beta冲刺 六 Beta冲刺 七 Beta总结 用户 ...

  6. Java控制台常用命令

    http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html javaw是java的带console版本,其他一致. h ...

  7. @Autowired的使用:推荐对构造函数进行注释

    在编写代码的时候,使用@Autowired注解是,发现IDE报的一个警告,如下: Spring Team recommends "Always use constructor based d ...

  8. Oracle的一般监听问题解决

    1. 无监听的解决办法: Windows的情况下重启之后或者是一些异常状态时会造成服务没有正常启动起来, 解决办法: 打开服务 方法1 任务管理器-服务界面 或者是 运行-services.msc 打 ...

  9. Oracle数据库 查看表是否是 索引组织表的方法

    1. 最近在工作过程中发现 一个表插入很慢 以为是索引组织表, 所以一直有点纠结 但是发现 产品里面是没有IOT的 于是找了下公司的OCP 问了下 如何查看 就是 user_tables 视图里面的一 ...

  10. 关于Http_build_query的用法

    使用背景:在做接口业务过程中,有时会遇到这种情况,本地APP需要接口给其返回一个url,那么在拼接参数的时候,用这个函数就会很方便. 百度百科上给的解释是这样的:http_build_query -- ...