2009-08-27 12 views
0

私はカスタムクラスのため、このコード「sau_timer」を持つ:ブーストスレッドとタイマー、C++

sau_timer::sau_timer(int secs, timerparam f, vector<string> params) : strnd(io), 
    t(io, boost::posix_time::seconds(secs)) 
{ 
    assert(secs > 0); 
    this->f = f; 
    this->params = params; 
    t.async_wait(strnd.wrap(boost::bind(&sau_timer::exec, this, _1))); 
    boost::thread thrd(boost::bind(&boost::asio::io_service::run, &io)); 
    io.run(); 
} 

void sau_timer::exec(const boost::system::error_code&) { 
    (f)(params); 
} 

を、私はそれをしたい私はsau_timerオブジェクトを作るとき、タイマーが起動し、それにプログラムの実行を許可するように、持続する。 (「こんにちは!」)

int main(int argc, char* argv[]) 
{ 
    vector<string> args(1); 
    args[0] = "Hello!"; 
    sau_timer timer_test(3, sau_prompt, args); 
    args[0] = "First!"; 
    sau_prompt(args); 
    timer_test.thrd.join(); 
    return 0; 
} 

ここに私の意図は、そのtimer_testがsau_promptを呼び出す前に3秒待機タイマーを開始、作られているが、そのsau_prompt(たとえば、これは()のメインである「ファースト!」 )が最初に呼び出されます。現在のところ、最初の前にプロンプ​​トにHelloが表示され、タイマーが3秒間プログラム全体を停止してから続行することを示しています。タイマーをバックグラウンドで実行します。

私は間違っていますか?コードはコンパイルされます...

ありがとうございます。

答えて

6

あなたはsau_timerで "io.run()"を呼び出しています。これは基本的にasio reactorにすべての保留中の非同期イベントを処理するよう指示します。

イベントを設定した後、runまたはpostを呼び出す必要があります。これはイベントが正常に実行された方法です。 asioドキュメントのサンプルをチェックしてください。

 
#include <iostream> 
#include <asio.hpp> 

#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp> 
#include <boost/lexical_cast.hpp> 
#include <boost/date_time.hpp> 
#include <boost/thread.hpp> 


class event_timer 
{ 
public: 

    event_timer(asio::io_service& io_service, 
       const std::size_t& tid, 
       const std::size_t& interval = 5) 
    : io_service_(io_service), 
    timer_(io_service), 
    tid_(tid), 
    interval_(interval), 
    tick_count_(0), 
    total_diff_(0) 
    { 
    } 

    void start() 
    { 
     timer_.cancel(); 
     initiate_timer(); 
    } 

    void stop() 
    { 
     timer_.cancel(); 
    } 

    void set_interval(const std::size_t& milliseconds) 
    { 
     interval_ = milliseconds; 
    } 

private: 

    inline void initiate_timer() 
    { 
     if (interval_) 
     { 
     timer_.expires_from_now(boost::posix_time::milliseconds(interval_)); 
     timer_.async_wait(
      boost::bind(&event_timer::handle_timer_event,this, 
       asio::placeholders::error)); 
     before_ = boost::posix_time::microsec_clock::universal_time(); 
     } 
    } 

    inline void handle_timer_event(const asio::error_code& error) 
    { 
     if (!error && interval_) 
     { 
     after_ = boost::posix_time::microsec_clock::universal_time(); 
     boost::posix_time::time_duration duration = after_ - before_; 
     total_diff_ += std::abs(interval_ - duration.total_milliseconds()); 
     ++tick_count_; 
     if (tick_count_ < 200) 
      initiate_timer(); 
     else 
      std::cout << "Timer["<< tid_ <<"]\tTick["<< tick_count_ <<"] Average Diff: " << total_diff_/(1.0 * tick_count_) << std::endl; 
     } 
    } 

    asio::io_service& io_service_; 
    std::size_t tid_; 
    std::size_t interval_; 
    std::size_t tick_count_; 
    asio::deadline_timer timer_; 
    boost::posix_time::ptime before_; 
    boost::posix_time::ptime after_; 
    std::size_t total_diff_; 
}; 

int main() 
{ 

    std::cout << "Timer Test" << std::endl; 

    asio::io_service io_service; 

    try 
    { 
     const std::size_t et_cnt = 1000; 
     std::vector<event_timer*> et_lst; 

     for(unsigned int i = 0; i < et_cnt; ++i) 
     { 
     et_lst.push_back(new event_timer(io_service,i,10)); 
     } 

     for(unsigned int i = 0; i < et_cnt;) 
     { 
     et_lst[i++]->start(); 
     } 

     std::size_t thread_pool_size = 100; 

     //Create a pool of threads to run all of the io_services. 
     std::vector<boost::shared_ptr<boost::thread> > threads; 
     for (std::size_t i = 0; i < thread_pool_size; ++i) 
     { 
     boost::shared_ptr<boost::thread> thread(new boost::thread(boost::bind(&asio::io_service::run, &io_service))); 
     threads.push_back(thread); 
     } 

     // Wait for all threads in the pool to exit. 
     for (std::size_t i = 0; i < threads.size(); ++i) 
     threads[i]->join(); 
     for(unsigned int i = 0; i < et_cnt; delete et_lst[i++]); 

    } 
    catch(std::exception& e) 
    { 
     std::cout << "Exception: " << e.what() << std::endl; 
     return 1; 
    } 

    return 0; 
} 
+0

\t timer_test.io.run(); sau_timer timer_test(3、sau_prompt、args)の行の下にあります。 main()でio.run()をクラスコンストラクタから削除しましたが、効果は変わりません。私は誤解したことを恐れる? – Xenoprimate

+7

サンプルコードは、asioの一般的な使用方法を理解するのに十分なはずです。実行するスレッドを作成するのではなく、オブジェクトがタイマーやレシーバオブジェクトと言うのではなく、io_servicesを実行する複数のスレッドを作成し、それらのスレッド化されたio_servicesがスレッド/同時の方法で非同期呼び出しを実行できるようにすることです。 –