2

複数のプロデューサー/コンシューマーと連携することを目的とした SharedQueue を作成しました。

class SharedQueue : public boost::noncopyable
{
public:
  SharedQueue(size_t size) : m_size(size){};
  ~SharedQueue(){};

  int count() const {return m_container.size();};
  void enqueue(int item);
  bool enqueue(int item, int millisecondsTimeout);

private:
  const size_t m_size;
  boost::mutex m_mutex;
  boost::condition_variable m_buffEmpty;
  boost::condition_variable m_buffFull;

  std::queue<int> m_container;
};

void SharedQueue::enqueue(int item)
{
  {
    boost::mutex::scoped_lock lock(m_mutex);
    while(!(m_container.size() < m_size)) 
    {
      std::cout << "Queue is full" << std::endl;
      m_buffFull.wait(lock);
    }
    m_container.push(item);
  }
  m_buffEmpty.notify_one();
}

int SharedQueue::dequeue()
{
  int tmp = 0;
  {
    boost::mutex::scoped_lock lock(m_mutex);

    if(m_container.size() == 0) 
    {
      std::cout << "Queue is empty" << std::endl;
      m_buffEmpty.wait(lock);
    }

    tmp = m_container.front();
    m_container.pop();
  }

  m_buffFull.notify_one();
  return tmp;
}


SharedQueue Sq(1000);


void producer()
{
  int i = 0;
  while(true)
  {
    Sq.enqueue(++i);
  }
}

void consumer()
{
  while(true)
  {
    std::cout  << "Poping: " << Sq.dequeue() << std::endl;
  }
}

int main()
{

  boost::thread Producer(producer);
  boost::thread Producer1(producer);
  boost::thread Producer2(producer);
  boost::thread Producer3(producer);
  boost::thread Producer4(producer);

  boost::thread Consumer(consumer);

  Producer.join();
  Producer1.join();
  Producer2.join();
  Producer3.join();
  Producer4.join();

  Consumer.join(); 

  return 0;
}

ご覧のとおり、boost::condition_variable を使用しています。パフォーマンスを向上させる方法はありますか?おそらく、他の同期方法を検討する必要がありますか?

4

2 に答える 2

1

合成テストではなく、実際のシナリオでは、実装で十分だと思います。

ただし、1 秒あたり 10 6以上の操作が予想され、Windows 用に開発している場合、ソリューションはそれほど良くありません。

  1. Windows では、従来、マルチスレッド クラスを使用している場合、Boost は非常にうまく機能しませんでした。ミューテックスの場合、CriticalSection オブジェクトは通常、はるかに高速です。cond.vars については、ブーストの作成者が、正し​​い Win32 APIを使用する代わりに車輪を再発明しています。

  2. Windows では、"I/O 完了ポート" と呼ばれるネイティブのマルチ プロデューサー/コンシューマー キュー オブジェクトが、可能なユーザー モード実装よりも数倍効果的であると期待しています。主な目標は I/O ですが、PostQueuedCompletionStatus APIを呼び出して、必要なものをキューに投稿しても問題ありません。唯一の欠点は、キューに上限がないため、キューのサイズを自分で制限する必要があることです。

于 2012-11-26T21:52:50.833 に答える
1

これはあなたの質問に対する直接的な回答ではありませんが、良い代替案になるかもしれません。

パフォーマンスをどれだけ向上させたいかによって、Disruptor パターンを確認する価値があるかもしれません: http://www.2robots.com/2011/08/13/ac-disruptor/

于 2012-11-26T22:32:05.240 に答える