0

比較的長時間実行されるスキャン手順をトリガーする「スキャン」メソッドを持つ C++ プログラムを開発しています。手順が完了すると、scan メソッドはオブザーバー パターンを使用して結果をオブザーバーに通知します。

スキャンごとに個別のスレッドを作成したいと思います。このようにして、複数のスキャンを同時に実行できます。各スキャン プロセスが完了すると、スキャン メソッドがリスナーに通知するようにします。

ブースト スレッド ライブラリによると、次のようなことができるようです。

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost::mutex io_mutex;

void scan(int scan_target, vector<Listener> listeners)  
{
  //...run scan 
  {
    boost::mutex::scoped_lock  
      lock(io_mutex);
    std::cout << "finished scan" << endl;
    // notify listeners by iterating through the vector
    // and calling "notify()

  }
}

int main(int argc, char* argv[])
{

  vector<Listener> listeners
  // create 
  boost::thread thrd1(
    boost::bind(&scan, 1, listeners));
  boost::thread thrd2(
    boost::bind(&scan, 2, listeners));
  //thrd1.join();
  //thrd2.join();
  return 0;
} 

これはおおよそ正しいように見えますか? リスナーへの呼び出しをミューテックスする必要がありますか? 結合をなくしても大丈夫ですか?

4

3 に答える 3

1

ロックが必要かどうかは、通知をどうするかによって異なります。シングルスレッドアクセスが必要なリスナーのみの通知機能にロックを入れると、より適切になると思います。

于 2009-04-28T03:42:31.647 に答える
0

Listener :: Notification()は複数のスレッドから呼び出されているため、Notify()に副作用がない限り、次の3つのいずれかを実行する必要があります。

  1. 外部ロック(あなたの例):Listener :: Notification()を呼び出す前にミューテックスを取得する
  2. 内部ロック:Listener :: Notification()は内部でロックを取得します
  3. ロックフリー:グーグルで「ロックフリーアルゴリズム」を検索

各オプションには長所/短所があります...

(私が思うに)必要なものについては、オプション1が適しています。

また、joinステートメントを保持する必要があります。そうしないと、スレッドがジョブを終了する前にmain()が終了する可能性があります。との使用も検討しboost::thread_pooljoint_allください。

于 2009-04-28T04:18:32.763 に答える
0

ブーストについてはわかりませんが、概念的には正しく見えます。状態の変化を通知したいオブザーバーがいます。「適格なイベント」が発生した場合、通知するオブザーバーのリスト(またはベクトルなど)を実行する必要があります。また、同時通知によって問題が発生しないようにする必要もあります。

(これがパターンに関するウィキペディアの記事です。)

于 2009-04-28T03:07:05.570 に答える