天天看點

伺服器設計筆記(1)-----定時器的實作(C++)

很久之前聽著名頁遊伺服器主程講座時,講到過定時器的實作,基本思路如下(易語言)

       while(true)

       {

             對定時器進行排序。

             for(周遊定時器)

             {

                   if 如果定時器到:

                          callback;

                   else

                           break; 

             } 

             usleep(20);

         }

        按照這個思路,我們繼續我們的設計:

1: 首先 定義一個thread類:

伺服器設計筆記(1)-----定時器的實作(C++)

/*

 * 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,

    };

    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_ */

伺服器設計筆記(1)-----定時器的實作(C++)

        實作代碼thread.cpp:

伺服器設計筆記(1)-----定時器的實作(C++)

view

code

伺服器設計筆記(1)-----定時器的實作(C++)

 * thread.cpp

#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);

伺服器設計筆記(1)-----定時器的實作(C++)

 2:定義定時器,和定時器線程:

         timerthread.h

伺服器設計筆記(1)-----定時器的實作(C++)

 * timer.h

#ifndef timer_h_

#define timer_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

    static timerthread* _instance;

    static timerthread* get_instance();

    virtual void* run(void);

    virtual ~timerthread();

    void register(timer _timer);

    void unregister(timer _timer);

    timerthread();

    list<timer> _timer_list;

extern unsigned int get_systime_clock();

#define timermanage timerthread::get_instance()

#endif /* timer_h_ */

伺服器設計筆記(1)-----定時器的實作(C++)

          實作代碼:timerthread.cpp

伺服器設計筆記(1)-----定時器的實作(C++)
伺服器設計筆記(1)-----定時器的實作(C++)

 * timer.cpp

#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;

伺服器設計筆記(1)-----定時器的實作(C++)

 3: 測試函數:

伺服器設計筆記(1)-----定時器的實作(C++)
伺服器設計筆記(1)-----定時器的實作(C++)

//============================================================================

// 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>

int handle_timeout()

    unsigned int time = get_systime_clock();

    printf("time out,%u\n",time);

int main()

    timer _timer;

    _timer.open(1,handle_timeout);

    timermanage->register(_timer);

    timermanage->start();

    getchar();

伺服器設計筆記(1)-----定時器的實作(C++)

目前存在的問題:定時不準,主要是由于usleep()之後 ,不能及時醒,這個是因為linux線程排程引起的。

改進的方向:1. timerthread 裡面的list換成優先隊列

                 2. 添加時間糾正,在測試中發現,每次大概慢100us左右,這對于長時間的定時器是緻命。

也想聽聽廣大網友的意見,感激不盡。 

繼續閱讀