Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多生产者/消费者绩效_C++_Multithreading_Performance_Boost - Fatal编程技术网

C++ 多生产者/消费者绩效

C++ 多生产者/消费者绩效,c++,multithreading,performance,boost,C++,Multithreading,Performance,Boost,我已经编写了一个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(in

我已经编写了一个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;
}
class SharedQueue:public boost::不可复制
{
公众:
SharedQueue(size\u t size):m\u size(size){};
~SharedQueue(){};
int count()常量{return m_container.size();};
无效排队(整数项);
布尔排队(整数项,整数毫秒刺激);
私人:
常数大小;
boost::mutex m_mutex;
boost::条件变量m_buffEmpty;
boost::条件变量m_buffFull;
std::队列m_容器;
};
void SharedQueue::排队(int项)
{
{
boost::mutex::作用域锁定(m_mutex);
而(!(m_container.size()std::cout在真实场景中,而不是合成测试中,我认为您的实现已经足够好了

但是,如果您希望每秒执行106次或更多操作,并且您正在为Windows开发,那么您的解决方案就不是那么好

  • 在Windows上,Boost在使用多线程类时通常非常糟糕。 对于互斥对象,CriticalSection对象通常要快得多。对于cond.vars, boost的作者正在重新发明轮子,而不是使用轮子

  • 在Windows上,我希望使用名为“I/O完成端口”的本机多生产者/消费者队列对象要比任何用户模式实现的效率高出几倍。它的主要目标是I/O,但是调用将任何您想要的内容发布到队列中是完全可以的。唯一的缺点是队列没有上限,因此您必须自己限制队列大小


  • 这不是对你问题的直接回答,但它可能是一个很好的选择


    根据您希望提高性能的程度,可能值得一看:

    您是如何衡量“性能”的?Chad,我指的是将数据放入队列和从队列中获取数据之间的时间。这是您的瓶颈吗?使用锁,一次只能有一个生产者/消费者与您的队列对象交互。删除条件变量可确保每个条件变量都能尽快进入锁。但这可能会导致饥饿。写入性能代码很难:)我真的建议在重新发明轮子之前先看看现有的工具。@d_E,恐怕如果你有大约100个线程,那么队列设计是性能问题中最小的一个(除非你在一个总内核数超过32个的胖服务器上运行,在这种情况下100个线程就可以了)。