C++无锁编程之循环缓冲


#1
class circular_buffer
{
public:
	circular_buffer(unsigned int buffer_size)
		: m_buffer_size(std::pow(2, std::ceil(std::log2(buffer_size))))
		, m_offset(0)
		, m_write_p(0)
		, m_read_p(0)
		, m_circle_buffer(NULL)
	{}
	~circular_buffer()
	{
		close();
	}
 
public:
 
	std::size_t open()
	{
		if (m_circle_buffer)
			delete[] m_circle_buffer;
		m_circle_buffer = new char[m_buffer_size];
		m_write_p = m_read_p = m_offset = 0;
		return m_buffer_size;
	}
	
	void close()
	{
		if (m_circle_buffer)
			delete[] m_circle_buffer;
	}
 
	unsigned int put_data(char* buffer, unsigned int len)
	{
		unsigned int l;
		len = std::min(len, m_buffer_size - m_write_p + m_read_p);
		/* first put the data starting from fifo->in to buffer end */
		l = std::min(len, m_buffer_size - (m_write_p & (m_buffer_size - 1)));
		std::memcpy(m_circle_buffer + (m_write_p & (m_buffer_size - 1)), buffer, l);
		/* then put the rest (if any) at the beginning of the buffer */
		std::memcpy(m_circle_buffer, buffer + l, len - l);
		m_write_p += len;
		return len;
	}
 
	unsigned int get_data(char* buffer, unsigned int len)
	{
		unsigned int l;
		len = std::min(len, m_write_p - m_read_p);
		/* first get the data from fifo->out until the end of the buffer */
		l = std::min(len, m_buffer_size - (m_read_p & (m_buffer_size - 1)));
		std::memcpy(buffer, m_circle_buffer + (m_read_p & (m_buffer_size - 1)), l);
		/* then get the rest (if any) from the beginning of the buffer */
		std::memcpy(buffer + l, m_circle_buffer, len - l);
		m_read_p += len;
		return len;
	}
 
private:
	unsigned int m_buffer_size;
	unsigned int m_write_p;
	unsigned int m_read_p;
	unsigned int m_offset;
	char* m_circle_buffer;
};

这是我工作中用到的一个无锁循环缓冲实现,其灵感来自己于 IBM 的这篇文章(透过 Linux 内核看无锁编程),并抄袭了关键部分的代码而实现!

代码虽少,但用途可不小,效率也是极高的!希望对大家有用!

另外,boost.lockfree中有好几个非常不错的无锁数据结构,相比起这个,boost.lockfree更有实用价值!


#2

本主题已置顶,它将始终显示在它所属分类的顶部。可以由版主解除置顶或者点击清除置顶按钮。


#3