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_;
};