3

ロックによるパフォーマンスの問題に直面しているこのコードがあります。以下のスケッチを参照してください(とにかく大きすぎる実際のコードを投稿することはできません):

XYZ::process()
{
  ...
  lock();
  processSharedData(id );
  unlock();
  ...
}

XYZ::processSharedData(obj id)
{
  obj a = accessDataAttr1(id);
  //do some integrity checks

  //evaluate some conditions and then
  func1(attr1, attr2, attr3, ...);

  obj b = accessDataAttr2(id);
  //do some integrity checks

  //evaluate some conditions and then
  func2(attr1, attr2, attr3, ...);

  obj c = accessDataAttr3(id);
  //do some integrity checks

  //evaluate some conditions and then
  func3(attr1, attr2, attr3, ...);

  //do some clean up
  return;
}

ここで、func1、func2、および func3 を lock/unlock スコープから移動したいと思います。そのための効率的な方法を提案してください。後で呼び出すために、関数呼び出しをパラメーターとともに保存する方法はありますか?

すべてのパラメーターをメンバー構造体に格納し、関数ポインターを std::list に格納するのはどうですか?

編集:

c++11 がまだ利用できないことを前に言及しなかったことをお詫びします。std:function と std:bind のないソリューションは、今のところ素晴らしいでしょう。

4

2 に答える 2

5

あなたがこれを行うことができることを確認してください:

typedef std::vector<std::function<void(void)>> f_list;

XYZ::process() {
  //our function list
  f_list fl;
  lock();
  fl=processSharedData(id );
  unlock();
  //invoke functions
  for(auto& f : fl) f();
}

f_list XYZ::processSharedData(obj id) {
  f_list fl;
  obj a = accessDataAttr1(id);
  //do some integrity checks

  fl.push_back(
       std::bind(&func1, attr1, attr2, attr3)
  );

  obj b = accessDataAttr2(id);
  //do some integrity checks

  //evaluate some conditions and then
  fl.push_back(
       std::bind(&func2, attr1, attr2, attr3)
  );
  //and so on
  return fl;
}

参照

http://en.cppreference.com/w/cpp/utility/functional/bind

http://en.cppreference.com/w/cpp/utility/functional/function

http://en.cppreference.com/w/cpp/container/vector

于 2012-10-28T12:18:07.677 に答える
4

111111 からの回答に基づいて構築するには、呼び出したい関数がXYZクラスのメンバー関数である場合、インスタンスを最初の引数として渡す必要があります。

fl.push_back(
    std::bind(&func1, this, attr1, attr2, attr3)
);

後で関数を呼び出すときに、C++11 の別の新機能を使用できます:範囲ベースの for ループ:

for (auto f : fl)
    f();
于 2012-10-28T12:22:49.840 に答える