环形缓冲区

        环形缓冲区。我的理解就是,开辟一块内存区域,然后会有操作不断地往里边存放数据,同时也会有操作从这块区域里边往外拿数据。主要用在网络编程中,数据接收线程接收客户端发送过来的数据,先存放到环形缓冲区中,然后数据处理线程再从里边逐条读取数据并处理。实现的重点有两点:1、保证存放数据的时候不会覆盖还未读取的数据、读取数据的时候不会重复读取已经读取过的数据;2、线程同步。

        下面是我实现的一个简单的环形缓冲区代码:

#ifndef __rbuf_h__
#define __rbuf_h__

#include <Windows.h>

class RBuf
{
public:
	RBuf	( int sz );
	~RBuf	();

	bool	init	();
	bool	initOk	();
	bool	empty	();
	bool	full	();
	bool	read	( char *data, int len );
	bool	write	( const char *data, int len );
	void	destroy	();

private:
	CRITICAL_SECTION	m_cs;
	int					m_sz;
	int					m_rpos;
	int					m_wpos;
	char				*m_buf;
	bool				m_bOk;
};

#endif // __rbuf_h__

#include "rbuf.h"

RBuf::RBuf( int sz )
	: m_sz( sz )
	, m_rpos( 0 )
	, m_wpos( 0 )
	, m_buf( NULL )
	, m_bOk( false )
{
	InitializeCriticalSection( &m_cs );
	init();
}

RBuf::~RBuf()
{
	destroy();
	DeleteCriticalSection( &m_cs );
}

bool RBuf::init()
{
	destroy();

	EnterCriticalSection( &m_cs );
	m_buf = new char[m_sz];
	if( NULL == m_buf )
		m_bOk = false;
	else {
		memset( m_buf, 0, sizeof(char) * m_sz );
		m_bOk = true;
		m_rpos = 0;
		m_wpos = 0;
	}
	LeaveCriticalSection( &m_cs );

	return m_bOk;
}

void RBuf::destroy()
{
	EnterCriticalSection( &m_cs );
	if( NULL != m_buf ) {
		delete []m_buf;
		m_buf = NULL;
	}
	LeaveCriticalSection( &m_cs );
}

bool RBuf::initOk()
{
	return m_bOk;
}

bool RBuf::empty()
{
	bool bret = false;
	EnterCriticalSection( &m_cs );
	if( m_rpos == m_wpos )
		bret = true;
	LeaveCriticalSection( &m_cs );
	return bret;
}

bool RBuf::full()
{
	bool bret = false;
	EnterCriticalSection( &m_cs );
	if( (m_wpos + 1) == m_rpos )
		bret = true;
	else if( (m_rpos == 0) && (m_wpos == (m_sz - 1)) )
		bret = true;
	LeaveCriticalSection( &m_cs );
	return bret;
}

bool RBuf::read( char *data, int len )
{
	if( empty() )
		return false;

	bool bret = false;

	EnterCriticalSection( &m_cs );
	if( m_rpos < m_wpos ) {
		if( m_wpos - m_rpos < len )
			bret = false;
		else {
			memcpy( data, m_buf + m_rpos, len );
			m_rpos += len;
			bret = true;
		}
	}
	else {
		if( m_sz - m_rpos >= len ) {
			memcpy( data, m_buf + m_rpos, len );
			m_rpos += len;
			if( m_rpos == m_sz )
				m_rpos = 0;
			bret = true;
		}
		else {
			int len1 = m_sz - m_rpos;
			if( m_wpos + len1 >= len ) {
				memcpy( data, m_buf + m_rpos, len1 );
				memcpy( data + len1, m_buf, len - len1 );
				m_rpos = len - len1;
				bret = true;
			}
			else
				bret = false;
		}
	}
	LeaveCriticalSection( &m_cs );

	return bret;
}

bool RBuf::write( const char *data, int len )
{
	if( full() )
		return false;

	bool bret = false;

	EnterCriticalSection( &m_cs );
	if( m_wpos < m_rpos ) {
		if( m_rpos - m_wpos < len )
			bret = false;
		else {
			memcpy( m_buf + m_wpos, data, len );
			m_wpos += len;
			bret = true;
		}
	}
	else {
		if( m_sz - m_wpos >= len ) {
			memcpy( m_buf + m_wpos, data, len );
			m_wpos += len;
			if( m_wpos == m_sz )
				m_wpos = 0;
			bret = true;
		}
		else {
			int len1 = m_sz - m_wpos;
			if( m_rpos + len1 > len ) {
				memcpy( m_buf + m_wpos, data, len1 );
				memcpy( m_buf, data + len1, len - len1 );
				m_wpos = len - len1;
				bret = true;
			}
			else
				bret = false;
		}
	}
	LeaveCriticalSection( &m_cs );

	return bret;
}

        下面是简单的测试代码以及测试结果:

#include "rbuf.h"
#include <stdio.h>
#include <time.h>
#include <string>
using namespace std;

typedef enum _em_data_type {
	dtInt,
	dtStr,
	dtSt,
	dtCount
} DataType;

typedef struct _st_data_header {
	DataType	dt;
	int			len;
} DataHeader;

typedef struct _st_st {
	char	c;
	float	f;
	char	s[128];
} St;

DWORD WINAPI readProc	( LPVOID param );
DWORD WINAPI writeProc	( LPVOID param );
bool		 readData	( RBuf *pbuf );
bool		 writeData	( RBuf *pbuf, DataType dt );

int main( void )
{
	RBuf rbuf( 1024 );
	if( !rbuf.initOk() ) {
		printf( "init rbuf failed\r\n" );
		return -1;
	}
	else
		printf( "init rbuf success\r\n" );

	HANDLE hWrite = CreateThread( NULL, 0, writeProc, &rbuf, 0, NULL );
	if( NULL == hWrite ) {
		printf( "create write thread failed\r\n" );
		return -1;
	}

	Sleep( 10 );

	HANDLE hRead = CreateThread( NULL, 0, readProc, &rbuf, 0, NULL );
	if( NULL == hRead ) {
		printf( "create read thread failed\r\n" );
		CloseHandle( hWrite );
		return -1;
	}

	WaitForSingleObject( hWrite, INFINITE );
	WaitForSingleObject( hRead, INFINITE );
	return 0;
}

DWORD WINAPI writeProc( LPVOID param )
{
	srand( (unsigned)time(NULL) );
	RBuf *pbuf = (RBuf*)param;
	for( int i = 0; i < 128; i++ ) {
		writeData( pbuf, (DataType)(i % dtCount) );
		Sleep( 1 );
	}
	return 0;
}

DWORD WINAPI readProc( LPVOID param )
{
	RBuf *pbuf = (RBuf*)param;
	int count = 0;
	while( 1 ) {
		if( count > 5 )
			break;

		if( readData(pbuf) ) {
			count = 0;
			Sleep( 1 );
		}
		else {
			count++;
			Sleep( 10 );
		}
	}
	return 0;
}

bool writeData( RBuf *pbuf, DataType dt )
{
	if( NULL == pbuf )
		return false;

	int		valueInt		= rand();
	char	valueStr[128]	= { 0 };
	St		valueSt			= { 0 };

	DataHeader header;
	header.dt = dt;
	switch( dt )
	{
		case dtInt:
			header.len = sizeof( int );
			break;

		case dtStr:
			{
				sprintf_s( valueStr, 128, "dtStr make random data %d", valueInt );
				header.len = strlen(valueStr) + 1;
			}
			break;

		case dtSt:
			{
				valueSt.c = rand() % 26 + 'a';
				valueSt.f = (float)valueInt / 10;
				sprintf_s( valueSt.s, 128, "dtSt make random data %d", valueInt );
				header.len = sizeof( St );
			}
			break;

		default:
			printf( "write data get incorrect data type\r\n" );
			return false;
	}

	char *data = new char[sizeof(DataHeader) + header.len];
	memcpy( data, &header, sizeof(DataHeader) );
	switch( dt ) {
		case dtInt:
			memcpy( data + sizeof(DataHeader), &valueInt, header.len );
			break;
		case dtStr:
			memcpy( data + sizeof(DataHeader), &valueStr, header.len );
			break;
		case dtSt:
			memcpy( data + sizeof(DataHeader), &valueSt, header.len );
			break;
	}

	if( !pbuf->write(data, sizeof(DataHeader) + header.len) ) {
		printf( "write data failed\r\n" );
		delete []data;
		return false;
	}
	else {
		switch( dt ) {
			case dtInt:
				printf( "write dtInt data: %d\r\n", valueInt );
				break;
			case dtStr:
				printf( "write dtStr data: %s\r\n", valueStr );
				break;
			case dtSt:
				printf( "write dtSt data: %c, %f, %s\r\n", valueSt.c, valueSt.f, valueSt.s );
				break;
		}
		delete []data;
		return true;
	}
}

bool readData( RBuf *pbuf )
{
	if( NULL == pbuf )
		return false;

	DataHeader header;
	if( !pbuf->read((char*)&header, sizeof(DataHeader)) )
		return false;

	char *data = new char[header.len];
	if( !pbuf->read(data, header.len) ) {
		delete []data;
		return false;
	}

	switch( header.dt ) {
		case dtInt:
			printf( "read dtInt data: %d\r\n", *((int*)data) );
			break;

		case dtStr:
			printf( "read dtStr data: %s\r\n", data );
			break;

		case dtSt:
			{
				St *pst = (St*)data;
				printf( "read dtSt data: %c, %f, %s\r\n", pst->c, pst->f, pst->s );
			}
			break;

		default:
			printf( "read unknown data\r\n" );
	}

	delete []data;
	return true;
}

init rbuf success
write dtInt data: 20471
write dtStr data: dtStr make random data 14713
write dtSt data: y, 1013.099976, dtSt make random data 10131
write dtInt data: 19480
write dtStr data: dtStr make random data 13095
write dtSt data: d, 3112.600098, dtSt make random data 31126
read dtInt data: 20471
write dtInt data: 5836
read dtStr data: dtStr make random data 14713
write dtStr data: dtStr make random data 16262
read dtSt data: y, 1013.099976, dtSt make random data 10131
write dtSt data: a, 3181.699951, dtSt make random data 31817
read dtInt data: 19480
write dtInt data: 400
read dtStr data: dtStr make random data 13095
write dtStr data: dtStr make random data 15085
read dtSt data: d, 3112.600098, dtSt make random data 31126
write dtSt data: m, 2668.300049, dtSt make random data 26683
read dtInt data: 5836
write dtInt data: 15743
read dtStr data: dtStr make random data 16262
write dtStr data: dtStr make random data 9180
read dtSt data: a, 3181.699951, dtSt make random data 31817
write dtSt data: f, 1957.599976, dtSt make random data 19576
read dtInt data: 400
write dtInt data: 20515
read dtStr data: dtStr make random data 15085
write dtStr data: dtStr make random data 3206
read dtSt data: m, 2668.300049, dtSt make random data 26683
write dtSt data: y, 1894.000000, dtSt make random data 18940
read dtInt data: 15743
write dtInt data: 19083
read dtStr data: dtStr make random data 9180
write dtStr data: dtStr make random data 17804
read dtSt data: f, 1957.599976, dtSt make random data 19576
write dtSt data: i, 906.900024, dtSt make random data 9069
read dtInt data: 20515
write dtInt data: 30365
read dtStr data: dtStr make random data 3206
write dtStr data: dtStr make random data 9740
read dtSt data: y, 1894.000000, dtSt make random data 18940
write dtSt data: e, 2996.100098, dtSt make random data 29961
read dtInt data: 19083
write dtInt data: 28334
read dtStr data: dtStr make random data 17804
write dtStr data: dtStr make random data 5338
read dtSt data: i, 906.900024, dtSt make random data 9069
write dtSt data: n, 1046.099976, dtSt make random data 10461
read dtInt data: 30365
write dtInt data: 21328
read dtStr data: dtStr make random data 9740
write dtStr data: dtStr make random data 14093
read dtSt data: e, 2996.100098, dtSt make random data 29961
write dtSt data: i, 3154.300049, dtSt make random data 31543
read dtInt data: 28334
write dtInt data: 4971
read dtStr data: dtStr make random data 5338
write dtStr data: dtStr make random data 26558
read dtSt data: n, 1046.099976, dtSt make random data 10461
write dtSt data: z, 905.500000, dtSt make random data 9055
read dtInt data: 21328
write dtInt data: 31376
read dtStr data: dtStr make random data 14093
write dtStr data: dtStr make random data 23820
read dtSt data: i, 3154.300049, dtSt make random data 31543
write dtSt data: u, 2982.600098, dtSt make random data 29826
read dtInt data: 4971
write dtInt data: 31113
read dtStr data: dtStr make random data 26558
write dtStr data: dtStr make random data 7779
read dtSt data: z, 905.500000, dtSt make random data 9055
write dtSt data: w, 279.899994, dtSt make random data 2799
read dtInt data: 31376
write dtInt data: 23861
read dtStr data: dtStr make random data 23820
write dtStr data: dtStr make random data 12287
read dtSt data: u, 2982.600098, dtSt make random data 29826
write dtSt data: r, 2291.800049, dtSt make random data 22918
read dtInt data: 31113
write dtInt data: 26515
read dtStr data: dtStr make random data 7779
write dtStr data: dtStr make random data 6059
read dtSt data: w, 279.899994, dtSt make random data 2799
write dtSt data: r, 1111.599976, dtSt make random data 11116
read dtInt data: 23861
write dtInt data: 32540
read dtStr data: dtStr make random data 12287
write dtStr data: dtStr make random data 7887
read dtSt data: r, 2291.800049, dtSt make random data 22918
write dtSt data: e, 2816.399902, dtSt make random data 28164
read dtInt data: 26515
write dtInt data: 26710
read dtStr data: dtStr make random data 6059
write dtStr data: dtStr make random data 30121
read dtSt data: r, 1111.599976, dtSt make random data 11116
write dtSt data: n, 2229.899902, dtSt make random data 22299
read dtInt data: 32540
write dtInt data: 15782
read dtStr data: dtStr make random data 7887
write dtStr data: dtStr make random data 7131
read dtSt data: e, 2816.399902, dtSt make random data 28164
write dtSt data: w, 1520.300049, dtSt make random data 15203
read dtInt data: 26710
write dtInt data: 6501
read dtStr data: dtStr make random data 30121
write dtStr data: dtStr make random data 12838
read dtSt data: n, 2229.899902, dtSt make random data 22299
write dtSt data: n, 1053.099976, dtSt make random data 10531
read dtInt data: 15782
write dtInt data: 9783
read dtStr data: dtStr make random data 7131
write dtStr data: dtStr make random data 6517
read dtSt data: w, 1520.300049, dtSt make random data 15203
write dtSt data: n, 695.599976, dtSt make random data 6956
read dtInt data: 6501
write dtInt data: 2456
read dtStr data: dtStr make random data 12838
write dtStr data: dtStr make random data 797
read dtSt data: n, 1053.099976, dtSt make random data 10531
write dtSt data: f, 2254.300049, dtSt make random data 22543
read dtInt data: 9783
write dtInt data: 23736
read dtStr data: dtStr make random data 6517
write dtStr data: dtStr make random data 22115
read dtSt data: n, 695.599976, dtSt make random data 6956
write dtSt data: n, 2087.699951, dtSt make random data 20877
read dtInt data: 2456
write dtInt data: 10121
read dtStr data: dtStr make random data 797
write dtStr data: dtStr make random data 3903
read dtSt data: f, 2254.300049, dtSt make random data 22543
write dtSt data: b, 622.299988, dtSt make random data 6223
read dtInt data: 23736
write dtInt data: 4630
read dtStr data: dtStr make random data 22115
write dtStr data: dtStr make random data 31327
read dtSt data: n, 2087.699951, dtSt make random data 20877
write dtSt data: e, 1429.599976, dtSt make random data 14296
read dtInt data: 10121
write dtInt data: 16406
read dtStr data: dtStr make random data 3903
write dtStr data: dtStr make random data 29295
read dtSt data: b, 622.299988, dtSt make random data 6223
write dtSt data: k, 376.700012, dtSt make random data 3767
read dtInt data: 4630
write dtInt data: 2753
read dtStr data: dtStr make random data 31327
write dtStr data: dtStr make random data 664
read dtSt data: e, 1429.599976, dtSt make random data 14296
write dtSt data: z, 3046.500000, dtSt make random data 30465
read dtInt data: 16406
write dtInt data: 3298
read dtStr data: dtStr make random data 29295
write dtStr data: dtStr make random data 4678
read dtSt data: k, 376.700012, dtSt make random data 3767
write dtSt data: m, 2124.600098, dtSt make random data 21246
read dtInt data: 2753
write dtInt data: 13614
read dtStr data: dtStr make random data 664
write dtStr data: dtStr make random data 32303
read dtSt data: z, 3046.500000, dtSt make random data 30465
write dtSt data: q, 2102.699951, dtSt make random data 21027
read dtInt data: 3298
write dtInt data: 21204
read dtStr data: dtStr make random data 4678
write dtStr data: dtStr make random data 17041
read dtSt data: m, 2124.600098, dtSt make random data 21246
write dtSt data: a, 57.599998, dtSt make random data 576
read dtInt data: 13614
write dtInt data: 20565
read dtStr data: dtStr make random data 32303
write dtStr data: dtStr make random data 6842
read dtSt data: q, 2102.699951, dtSt make random data 21027
write dtSt data: s, 25.100000, dtSt make random data 251
read dtInt data: 21204
write dtInt data: 4246
read dtStr data: dtStr make random data 17041
write dtStr data: dtStr make random data 14798
read dtSt data: a, 57.599998, dtSt make random data 576
write dtSt data: s, 2495.699951, dtSt make random data 24957
read dtInt data: 20565
write dtInt data: 8756
read dtStr data: dtStr make random data 6842
write dtStr data: dtStr make random data 197
read dtSt data: s, 25.100000, dtSt make random data 251
write dtSt data: g, 676.299988, dtSt make random data 6763
read dtInt data: 4246
write dtInt data: 15639
read dtStr data: dtStr make random data 14798
write dtStr data: dtStr make random data 21939
read dtSt data: s, 2495.699951, dtSt make random data 24957
write dtSt data: u, 412.000000, dtSt make random data 4120
read dtInt data: 8756
write dtInt data: 15946
read dtStr data: dtStr make random data 197
write dtStr data: dtStr make random data 76
read dtSt data: g, 676.299988, dtSt make random data 6763
write dtSt data: y, 383.299988, dtSt make random data 3833
read dtInt data: 15639
write dtInt data: 5641
read dtStr data: dtStr make random data 21939
write dtStr data: dtStr make random data 12199
read dtSt data: u, 412.000000, dtSt make random data 4120
write dtSt data: n, 1903.300049, dtSt make random data 19033
read dtInt data: 15946
write dtInt data: 23580
read dtStr data: dtStr make random data 76
write dtStr data: dtStr make random data 3394
read dtSt data: y, 383.299988, dtSt make random data 3833
write dtSt data: g, 1313.300049, dtSt make random data 13133
read dtInt data: 5641
write dtInt data: 32356
read dtStr data: dtStr make random data 12199
write dtStr data: dtStr make random data 327
read dtSt data: n, 1903.300049, dtSt make random data 19033
write dtSt data: j, 1533.900024, dtSt make random data 15339
read dtInt data: 23580
write dtInt data: 15796
read dtStr data: dtStr make random data 3394
write dtStr data: dtStr make random data 3085
read dtSt data: g, 1313.300049, dtSt make random data 13133
write dtSt data: d, 2322.300049, dtSt make random data 23223
read dtInt data: 32356
write dtInt data: 27874
read dtStr data: dtStr make random data 327
write dtStr data: dtStr make random data 22754
read dtSt data: j, 1533.900024, dtSt make random data 15339
write dtSt data: s, 2518.199951, dtSt make random data 25182
read dtInt data: 15796
write dtInt data: 9757
read dtStr data: dtStr make random data 3085
write dtStr data: dtStr make random data 28168
read dtSt data: d, 2322.300049, dtSt make random data 23223
write dtSt data: q, 42.299999, dtSt make random data 423
read dtInt data: 27874
write dtInt data: 27264
read dtStr data: dtStr make random data 22754
write dtStr data: dtStr make random data 7677
read dtSt data: s, 2518.199951, dtSt make random data 25182
write dtSt data: z, 3267.800049, dtSt make random data 32678
read dtInt data: 9757
write dtInt data: 24552
read dtStr data: dtStr make random data 28168
write dtStr data: dtStr make random data 7679
read dtSt data: q, 42.299999, dtSt make random data 423
write dtSt data: x, 209.899994, dtSt make random data 2099
read dtInt data: 27264
write dtInt data: 8451
read dtStr data: dtStr make random data 7677
write dtStr data: dtStr make random data 26064
read dtSt data: z, 3267.800049, dtSt make random data 32678
read dtInt data: 24552
read dtStr data: dtStr make random data 7679
read dtSt data: x, 209.899994, dtSt make random data 2099
read dtInt data: 8451
read dtStr data: dtStr make random data 26064
请按任意键继续. . .


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值