服务器设计笔记(1)-----定时器的实现(C++)

简介: <p style="margin:5px auto; padding-top:0px; padding-bottom:0px; line-height:19px; font-size:13px; font-family:verdana,'ms song',宋体,Arial,微软雅黑,Helvetica,sans-serif; background-color:rgb(254,254,242

很久之前听著名页游服务器主程讲座时,讲到过定时器的实现,基本思路如下(易语言)

       while(true)

       {

             对定时器进行排序。

             for(遍历定时器)

             {

                   if 如果定时器到:

                          callback;

                   else

                           break; 

             } 

             usleep(20);

         }

        按照这个思路,我们继续我们的设计:

1: 首先 定义一个Thread类:

         

复制代码
/*
 * Thread.h
 *
 *  Created on: Sep 11, 2012
 *      Author: root
 
*/

#ifndef THREAD_H_
#define THREAD_H_

#include <pthread.h>

class Thread {

public:
     enum THREADSTATE
    {
        IDLE,
        WORK,
        BUSY,
    };

public:

    Thread();

     virtual ~Thread();

     virtual  void* run( void) =  0;

     virtual  int start( void);

     virtual  int cancel( void);

    pthread_t get_pid()  const
    {
         return pid;
    }

protected:

    THREADSTATE _thread_state;

private:

    pthread_t pid;

     static  void* thread_entry( void* para);
};

#endif /* THREAD_H_ */
复制代码

        实现代码Thread.cpp:

View Code
复制代码
/*
 * Thread.cpp
 *
 *  Created on: Sep 11, 2012
 *      Author: root
 
*/

#include  " Thread.h "

Thread::Thread() {
     //  TODO Auto-generated constructor stub

}

Thread::~Thread() {
     //  TODO Auto-generated destructor stub
}

void* Thread::thread_entry( void* para)
{
    Thread *pThread = static_cast<Thread *>(para);
     return pThread->run();
}

int Thread::start( void)
{
     if(pthread_create(&pid, 0,thread_entry,static_cast< void *>( this)) <  0)
    {
        pthread_detach( this->pid);
         return - 1;
    }
     return  0;
}

int Thread::cancel( void)
{
    pthread_cancel( this->pid);
     return  0;
}
复制代码

 2:定义定时器,和定时器线程:

         TimerThread.h

         

复制代码
/*
 * Timer.h
 *
 *  Created on: Sep 11, 2012
 *      Author: root
 
*/

#ifndef TIMER_H_
#define TIMER_H_

#include  " Thread.h "
#include <list>

using  namespace std;

struct Timer
{

     void *_args;
     int (*_callback)();
     int _interval;
     int leftsecs;
     void open( int interval, int (*callback)())
    {
        _interval = interval *  1000;
        leftsecs = _interval;
        _callback = callback;
    }

     bool  operator < (Timer _timer)
    {
         return _timer.leftsecs <  this->leftsecs;
    }

     bool  operator == (Timer _timer)
    {
         return _timer.leftsecs ==  this->leftsecs;
    }

};

class TimerThread :  public Thread
{

public:

     static TimerThread* _instance;

     static TimerThread* get_instance();

     virtual  void* run( void);

     virtual ~TimerThread();

     void Register(Timer _timer);

     void unRegister(Timer _timer);

private:

    TimerThread();

    list<Timer> _timer_list;

};

extern unsigned  int get_systime_clock();



#define TIMERMANAGE TimerThread::get_instance()

#endif /* TIMER_H_ */
复制代码

 

          实现代码:TimerThread.cpp

View Code
复制代码
/*
 * Timer.cpp
 *
 *  Created on: Sep 11, 2012
 *      Author: root
 
*/

#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include  " Timer.h "


TimerThread* TimerThread::_instance;



TimerThread::TimerThread()
{

}

TimerThread::~TimerThread()
{

}

void* TimerThread::run( void)
{
     while( true)
    {
        unsigned  int start_clock = get_systime_clock();
         this->_timer_list.sort();
        list<Timer>::iterator iter;
         for(iter =  this->_timer_list.begin();
                iter !=  this->_timer_list.end();
                    iter ++)
        {
            iter->leftsecs --;
             if(iter->leftsecs ==  0)
            {
                iter->_callback();
                iter->leftsecs = iter->_interval;
            }
        }
        unsigned  int end_clock = get_systime_clock();

        usleep( 1000 + start_clock - end_clock);
    }
     return ( void*) 0;
}

void TimerThread::Register(Timer _timer)
{
     this->_timer_list.push_back(_timer);
}

void TimerThread::unRegister(Timer _timer)
{
     this->_timer_list.remove(_timer);
}

TimerThread* TimerThread::get_instance()
{
     if(_instance == NULL)
    {
        _instance =  new TimerThread();
    }
     return _instance;
}



unsigned  int get_systime_clock()
{
     struct timeval now;
    gettimeofday(&now,NULL);
     return now.tv_sec* 1000 + now.tv_usec/ 1000;
}
复制代码

          

 3: 测试函数:

View Code
复制代码
// ============================================================================
//  Name        : test.cpp
//  Author      : archy
//  Version     :
//  Copyright   : Your copyright notice
//  Description : Hello World in C++, Ansi-style
// ============================================================================

#include <iostream>
#include < string>
#include <stdio.h>
#include <sys/types.h>

#include  " Timer.h "


using  namespace std;

int handle_timeout()
{
    unsigned  int time = get_systime_clock();
    printf( " time out,%u\n ",time);
     return  0;
}

int main()
{
    Timer _timer;
    _timer.open( 1,handle_timeout);
    TIMERMANAGE->Register(_timer);
    TIMERMANAGE->start();
    getchar();
     return  0;
}
复制代码

       

目前存在的问题:定时不准,主要是由于usleep()之后 ,不能及时醒,这个是因为Linux线程调度引起的。

改进的方向:1. TimerThread 里面的list换成优先队列

                 2. 添加时间纠正,在测试中发现,每次大概慢100us左右,这对于长时间的定时器是致命。

也想听听广大网友的意见,感激不尽。 

相关文章
|
1天前
|
云安全 人工智能 自然语言处理
AI说的每一句话,都靠谱吗?
阿里云提供AI全栈安全能力,其中针对AI输入与输出环节的安全合规挑战,我们构建了“开箱即用”与“按需增强”相结合的多层次、可配置的内容安全机制。
|
5天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
8天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
2天前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
296 192
|
2天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
311 164
|
1天前
|
开发者
「玩透ESA」ESA启用和加速-ER在加速场景中的应用
本文介绍三种配置方法:通过“A鉴权”模板创建函数并设置触发器路由;在ESA上配置回源302跟随;以及自定义响应头。每步均配有详细截图指引,帮助开发者快速完成相关功能设置,提升服务安全性与灵活性。
291 2
|
7天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
453 93