1

boost我使用and编写了一个小类std::stringstream来提供并发std::ostream支持。该类需要提前知道线程的数量(即使这种行为可以调整),并且该类使用通道的概念来识别不同的线程,以最大限度地减少资源并发,输出整个块并避免阻塞,该类缓冲对象中每个线程的输入stringstream。当线程调用 flush() 时,如果ostream资源不忙或缓冲区已满,缓冲区将被刷新。

您是否看到此实现有任何(性能)​​问题?特别是,使用通道我试图限制stringstream对象构造的数量。有没有一种好方法可以告诉stringstream对象要分配的字符串的长度?是否值得使用 char 数组进行缓冲?我选择stringstream它不仅是因为它易于使用,而且因为我ostream在 ()-operator 成员函数中实现了完全兼容。

#include <boost/thread.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include<ostream>
#include<sstream>

class ConcurrentOutStream {
  public:
    ConcurrentOutStream( std::ostream& os, const uint channels, const uint buffer_size ) :
      os_( os ),
      max_buffer_size_( buffer_size ),
      buffers_( channels )
      {
        for ( uint i=0; i<threads; ++i ) buffers_.push_back( new std::ostringstream ); //because streams are not copyable
      };

    ~ConcurrentOutStream() {
      for ( uint i=0; i<buffers_.size(); ++i ) forceFlush( i );
    }

    std::ostream& operator()( const uint channel ) { return buffers_[channel]; }

    void flush( const uint channel ) {
      if ( buffers_[channel].str().size() < max_buffer_size_ ) tryFlush( channel );
      else forceFlush( channel );
    }

    const uint channels() { return buffers_.size(); };

  protected:
    void tryFlush( const uint channel ) { // write if ostream not busy
      if ( mutex_.try_lock() ) {
        os_ << buffers_[channel].str();
        buffers_[channel].str("");
        mutex_.unlock();
      }
    }

    void forceFlush( const uint channel ) {
      if ( ! buffers_[channel].str().empty() ) {
        boost::mutex::scoped_lock( mutex_ );
        os_ << buffers_[channel].str();
        buffers_[channel].str("");
      }
    }

    std::ostream& os_;
    const uint max_buffer_size_;
    boost::ptr_vector< std::ostringstream > buffers_;
    boost::mutex mutex_;
};
4

0 回答 0