2012-03-17 13 views
1

私のプロジェクトでは、すべてのクラスオブジェクトには、オブジェクト関数が実行される無限サイクル(while(1))の内部に独自のスレッドがあります。私はすべてのオブジェクトがタイマーと非同期にその機能を実行するようにこれを変更しようとしています。boost :: threadsからboost :: asioタイマーへ

基本的に、これはそれが無限ループでスレッドでどのように動作するかです:

class obj 
{ 
    public: 
      obj(); 
      ~obj(); 
     //custom functions and variables 
     int x; 
     int obj_action; 
     move(); 
     wait(); 

} 

obj() 
{ 
    obj_action=1; 
    //when constructing object, make its thread with infinite while cycle 
    boost::thread make_thread(boost::bind(&obj::obj_engine,this)); 
} 

void obj::obj_engine() 
{ 
    while(true) 
    { 
     if (obj_action==1){move();} 
     else if (obj_action==2){wait();} 
     Sleep(1); 
    } 
} 

void obj::move() 
{ 
     x++; 
     obj_action==2; 
} 


void obj::wait() 
{ 
     Sleep(5000); 
     obj_action==1; 
} 

この例では、コンストラクタを持つOBJクラス、デストラクタ、変数や関数のカップルのカップルを示しています。 オブジェクト(obj())を構築するときに、スレッドが作成されます。スレッドには関数obj_engineが含まれ、無限ループ(while(true))を持ちます。ループには2つの関数があります: 1. wait() - スレッドを5秒間スリープさせます。 2. walk() - 単純にx + 1 これらの2つの関数は、obj_actionを定義することによって終了後に互いに切り替えます。

ここでは、非同期的にmove()関数が実行され、move()関数の後で非同期にwait()関数が実行され、その逆の場合にこれを変更します。だから私はスレッドを使用する必要はありません。

私はこのような結果を期待:

//constructing 
obj() 
{ 
     asynchronous(walk()); 
} 

walk() 
{ 
    x++ 
    asynchronous(wait()); 
} 

wait() 
{ 
    Sleep(5000); 
    asynchronous(walk()); 
} 

私はあなたがブースト:: ASIOタイマーで、これを行うことができます聞いたが、私は本当に方法がわかりません。 誰かが私に方法を教えてくれたら、とても感謝しています。ここで

+0

ここで私の最初のソースコードにメモリリークがあったので、私の答えの更新を見てください。ごめんなさい。 – nijansen

答えて

2

あなたが行く:this tutorial shows you how to use an asynchronous timer、およびthis tutorial shows you how to reset your timer

#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 



class obj { 
public: 
    obj() : x_(0), t_(io_service_, boost::posix_time::seconds(5)) { 
     t_.async_wait(boost::bind(&obj::move, this)); 
     io_service_.run(); 
    } 

    void move() { 
     x_++; 
     std::cout << x_ << std::endl; 
     t_.expires_at(t_.expires_at() + boost::posix_time::seconds(5)); 
     t_.async_wait(boost::bind(&obj::move, this)); 
    } 

private: 
    int x_; 
    boost::asio::io_service io_service_; 
    boost::asio::deadline_timer t_; 
}; 

int main(int, char**) { 
    obj a; 
    while(true); 
} 

基本的にはあなたが必要とするすべてはASIOチュートリアルで覆われています。

更新:

代わりに私の最初の1の上記のソースコードを使用してください - によるio_service_.run()の繰り返し呼び出しに、各move呼び出しが別のスレッドで呼び出されることになるといくつかの時間後にアプリケーションが原因でクラッシュしましたそれの。上記のコードはこの問題を解決し、そのようにしてwait関数を取り除きます。 nijansenから例を借り

+0

しかし、さらにオブジェクトを追加しようとすると: obj; obj b; obj c; そのようなコンストラクタが初期化を完了しないという結果が得られます。私はすべてのオブジェクトがこれらの機能を別々に実行することを望んでいます。今では最初のオブジェクトを印刷します。x ++(1,2,3,4,5) 私は結果を期待していました。(111,222,333,444,555)スレッドを使用した例 –

2

は、私は一緒にあなたが(私が思う)欲しいものに類似であるべき何かをホイップしました。

io_serviceは、すべてのオブジェクトのスケジューリング間で共有する必要があります。通常、スレッドごとに1つのio_serviceがありますが、より複雑なスキームも同様に使用できます。 io_service::runは、io_serviceでスケジュールされた作業がある間(タイムアウトの保留中またはソケット上で待機中)実行されます。それ以上の作業がスケジュールされていない場合は、単に戻ります。

io_service::postは、 "アクティブオブジェクト"(異なるio_servicesと異なるスレッドの下で動作している場合でも動作します)間でメッセージを送信する方法として興味があります。 boost::bindとおそらくboost::signalsを見たいかもしれません。

#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 

namespace asio = boost::asio; 

class obj { 
public: 
    obj(asio::io_service& ioSvc) 
     : x_(0), t_(ioSvc) 
    { 
     schedule_in(5); 
    } 

    void schedule_in(int seconds) { 
     t_.expires_from_now(boost::posix_time::seconds(3)); 
     t_.async_wait(boost::bind(&obj::move, this)); 
    } 

    void move() { 
     x_++; 
     std::cout << x_ << std::endl; 
     schedule_in(5); 
    } 

private: 
    int x_; 
    boost::asio::deadline_timer t_; 
}; 

int main(int, char**) { 
    boost::asio::io_service io_service; 
    obj a(io_service); 
    obj b(io_service); 
    obj c(io_service); 
    io_service.run(); 
} 
+0

ありがとうございます。私の最後の質問は次のようなものです:ゲームサーバー内のすべてのオブジェクトにスレッドよりも同期タイマーを使用する方が良いですか? 「より良い」と言えば、効率性、メモリ使用量、そして普及している変種でしょうか? –

+1

私は間違いなくオブジェクトごとにスレッドを保持しません。部分的には、オブジェクト(数百または数千)のロットに対して、オーバヘッド、同期が実際の問題になります。また、少数のオブジェクトであっても、スレッド間の同期と通信は非常に難しくなります。 本当にあなたが書いているサーバーなら、非同期IOモデルが間違いなく道のりです。それはスケールがよく示されており、 "イベント"処理のためのまともなモデルです。 サーバーでCPUを大量に使用するタスクがある場合は、io_serviceを複数のスレッドに分割するか、重い作業をしているバックグラウンドスレッドプールを維持することができます。 – Rawler