boost::asio でタイマーを実装する
これは、私たちのプロジェクトで使用したタイマー クラスのウィッチです。ウィッチ プロジェクトは、4Gbit/s のインターネット フロー (約 300 万から 400 万のタイマー) を扱います。タイマーは、ほとんどの一般的な作業に適しています。
timer.h
/*
* Timer
* Licensed under Apache
*
* Author: KaiWen <wenkai1987@gmail.com>
* Date: Apr-16-2013
*
*/
#ifndef TIMER_H
#define TIMER_H
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/unordered_map.hpp>
typedef boost::asio::deadline_timer* timer_ptr;
namespace bs = boost::system;
class timer;
class timer_node;
class tm_callback {
public:
explicit tm_callback(boost::function<void(timer_node&)>& f) : m_f(f)
{
}
void operator()(timer_node& node, const bs::error_code& e) {
if (!e)
m_f(node);
}
private:
boost::function<void(timer_node&)> m_f;
};
class timer_node {
friend class timer;
public:
timer_node() {}
timer_node(timer_ptr p, int ms, boost::function<void(timer_node&)> f) :
m_tptr(p), m_ms(ms), m_callback(f)
{
}
void reset(unsigned int ms = 0, boost::function<void(timer_node&)> f = 0) {
if (ms)
m_tptr->expires_from_now(boost::posix_time::milliseconds(ms));
else
m_tptr->expires_from_now(boost::posix_time::milliseconds(m_ms));
if (f)
m_tptr->async_wait(boost::bind<void>(tm_callback(f), *this, _1));
else
m_tptr->async_wait(boost::bind<void>(tm_callback(m_callback), *this, _1));
}
private:
timer_ptr m_tptr;
int m_ms;
boost::function<void(timer_node&)> m_callback;
};
タイマー.cpp
/*
* Timer
*
* Licensed under Apache
*
* Author: KaiWen <wenkai1987@gmail.com>
* Date: Apr-16-2013
*
*/
#include "timer.h"
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
namespace ba = boost::asio;
timer::timer(int thread_num) : m_next_ios(0), m_size(0) {
for (int i = 0; i < thread_num; i++) {
io_service_ptr p(new ba::io_service);
work_ptr pw(new ba::io_service::work(*p));
m_ios_list.push_back(p);
m_works.push_back(pw);
}
pthread_spin_init(&m_lock, 0);
}
timer::~timer() {
pthread_spin_destroy(&m_lock);
}
void timer::run() {
for (size_t i = 0; i < m_ios_list.size(); i++)
m_threads.create_thread(boost::bind(&ba::io_service::run, &*m_ios_list[i]))->detach();
}
必要に応じて、timer.cpp を timer.h に結合すると、ヘッダー ファイルだけになります。簡単な使い方:
#include <stdio.h>
#include "timer.h"
timer t(3);
void callback(timer_node& nd) {
std::cout << "time out" << std::endl;
t.del_timer(nd);
}
int main(void) {
t.run();
t.add_timer(5000, callback); // set timeout 5 seconds
sleep(6);
return 0;
}
スレッド特殊タイマーを実装する
上記のタイマーにロックがあり、プログラムがあまり速くありません。オーウェンスレッドの特別なタイマーを実装できます。ロックを使用せず、ブロックせず、上記のタイマーよりも高速ですが、これには「ドライバー」が必要であり、実装はほとんどありません。これを実装する方法は次のとおりです。
pkt = get_pkt();
if (pkt) {
now = pkt->sec;
timer.execut_timer(now);
}
さて、ここではロックもブロックもせず、パフォーマンスを向上させます。これを使用して、10GBit/s のインターネット フロー (約 800 万から 900 万のタイマー) を処理します。しかし、これは実装依存です。お役に立てれば幸いです。