boost :: shared_ptr <boost :: thread>でオブジェクトを識別する


2

私はブーストウェブサイトの例に基づいてアプリケーションを構築しています。これらは、以下の知るべき関連定義である。

 
typedef boost::shared_ptr< connection > connection_ptr; 
std::set< connection_ptr> connections_; 
std::vector< boost::shared_ptr< boost::thread> > threads; 

ここで、接続はクラスである。ファイルの1、connection_manager.cpp

、彼らはこのようにやっている:今

 
void connection_manager::start(connection_ptr c) 
{ 
    connections_.insert(c); 
    c->start(); 
} 

、私は私のプログラムの構造のため、別のスレッド内のすべての新しい接続を開始したいです。だから私はに応じて上記を変更した:

 
void connection_manager::start(connection_ptr c) 
{ 
    boost::shared_ptr< boost::thread > thread(new boost::thread(
         boost::bind(&connection::start, c))); 

    // push the newely created thread into the vector 
    threads.push_back(thread); 

    // save the connection in our set 
    connections_.insert(c); 
} 

私の問題、ひいてはこの質問を、私はこれらのconnection_オブジェクトの一つだけにしたいとき、あります。以前提供されたリンクでは、彼らは次のように実行します。

 
void connection_manager::stop(connection_ptr c) 
{ 
    connections_.erase(c); 
    c->stop(); 

    // find the connection in among the threads and join that thread 
} 

しかし、上記のコメントは、どのように私はすべてのスレッドの中で、Cを見つけるだけでそのスレッドを停止しない、示唆するように。私は、そのスレッドのjoin()関数を呼び出したいと思います。


更新:

私はこれは私が本当にしたいものを実際にあると思います!そこで変数を宣言します。

 
std::map < connection_ptr, boost::shared_ptr < boost::thread > > threads; 

しかし、以前と同じ方法で新しいトレッドを作成するにはどうすればよいですか? Like:

 
boost::shared_ptr < boost::thread > thread(new boost::thread(
         boost::bind(&connection::start, c))); 

しかし、次のステップは何ですか?あなたの代わりにベクトルのマップ(または他の連想コンテナ)を使用している場合は混同されているため申し訳ありません... :-)

2

あなたのネットワークとスレッド間の関連を維持することができます

std::map<connection_ptr, boost::shared_ptr<boost::thread> > threads; 

は、あなたが書くことができます:

threads[connection]->stop(); 
:あなたは、スレッドとを作成した後、代わりに一back呼び出しの

threads[connection] = thread; 

後でルックアップしたいときはにしてください。

NB:スレッドとネットワーク接続の間に1:1マッピングを維持する一般的なコメントアプリケーションは、サービス拒否(DoS)攻撃に対して非常に脆弱です。

  0

ちょうど私があなたを正しく理解しているように:あなたが目的に沿って地図を持っていれば、それはかなり脆弱なものでしょうか?代わりに私はどうすればいいですか? 14 5月. 112011-05-14 10:24:32

  0

問題は、誰かがあなたのアプリケーションに接続するプログラムを1秒間に100回書くのは非常に簡単だということです。スレッドを作成するには、スレッドごとに必要なRAMとCPU時間がかなりかかります。これらの接続のそれぞれが新しいスレッドを作成した場合(そしてそれをさらに結びつける場合)、システムのパフォーマンスは徐々に低下します。通常の解決方法は、[スレッドプール](http://stackoverflow.com/questions/4084777/creating-a-thread-pool-using-boost)を使用して固定数のスレッドを作成し、各スレッドを共有することですいくつかの接続の間。 14 5月. 112011-05-14 14:27:54

  0

私はこれを理解しようとしています。助けてくれてありがとう。 "複数の接続間で各スレッドを共有する"とは、[HTTP Server 2の例](http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/example/http/server2 /io_service_pool.cpp)。 io_servicesは異なるスレッドで作成されます。新しい接続では、これらのいずれかを使用しています。これはあなたが意味することですか?プログラムフローが異なるスレッドにioサービスを持つことは、どういう意味ですか?それはまた、(例えば、async_read()のコールバック)は別のスレッドで実行されるでしょうか? 15 5月. 112011-05-15 07:39:19

+1

それは私が提案していたもののように見えます。 (私はASIOでこれを行うより良い方法があると思ったが、確かに覚えていない)。基本的に何が起こるかは、接続の数が少ない場合は接続の数>接続数のため、基本的に1:1の接続:スレッドの比率が得られます。 1つのスレッドで複数の接続が処理されるようになりますが、接続の数が増えるにつれて、パフォーマンスは向上します。 15 5月. 112011-05-15 08:48:51

  0

私はそれを得る、ありがとう!しかし、より良いパフォーマンスを得るには、どうすればよいとお考えですか?私はこのパフォーマンス/スレッドのことをかなり新しくしています。そのため、HTTP Server 2の例でより良いパフォーマンスを得るために変更できるものはありますか? 15 5月. 112011-05-15 09:44:08

  0

HTTPサーバー2のパフォーマンスでは、a)適切な数のスレッドを使用して要求を処理し、参照する "現実的な"作業負荷のベンチマークと、b)すべての要求が比較的等しい場合のパフォーマンスが良いと思われます。簡単な要求があり、複雑な要求がある場合は、ラウンドロビンの選択が最適ではない可能性があります。 15 5月. 112011-05-15 13:02:29

  0

ありがとう!私の場合、これは良い解決策になると思います。ちょうどもう1つの質問:io_servicesが異なるスレッドで実行されるということは、それらを使用する接続が別のスレッドで実行されることを意味しますか?つまり、接続はio_serviceと同じスレッドで実行されますか? 16 5月. 112011-05-16 06:04:13

  0

@ThomasJohanssonはい、非同期コールバックはio_serviceと同じスレッドで実行されます。 (1つのio_serviceオブジェクトを複数のスレッドで処理することもできます(http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/tutorial/tuttimer5.htmlを参照してください)。 awoodlandの回答にupvote、あなたが受け取った答えの一つを受け入れる!) 13 2月. 122012-02-13 01:44:33


1

接続が常にスレッドにバインドされている場合は、接続オブジェクトが実行中のスレッドを指しているだけで、スレッドで開始するロジックを接続クラス自体に移動するのが理にかなっています。