作者:
www.cppblog.com/true 2011年1月13日星期四
最近几天一直在思考一个问题:我们需要什么样的网络基础开发包?libevent,asio,ace,还是自己封装?每种选择都有他的理由,至于性能方面都差不多,因为都是对底层API的封装嘛,以前在linux下简单测试过libevent和ace的dev_poll_reactor,基本持平,现在代码没找到,有机会再做个全面对比。我现在比较关心这个问题:如何继承自己的内存池?按这个思路,libevent应该是不行了,没有这方面的接口;ace这个既臃肿又强大的东西肯定可以,不过他的ACE_Message_Block还是太复杂,不信的话,找一天时间看看他的代码,能搞懂他的成员函数不:),我上家公司的服务器平台都是基于ace的,版本是5.4,一直都很稳定,稳定归稳定,当时是花费了大量的时间的,以目前我的观察,越来越多的人不愿意接受这种几天也写不出代码的东西了。对于boost,我一直是若即若离,接触他是因为他的库可能出现在标准里面,抵触他是因为他的模板的使用,语法细节太多了,不直观。至少现在还没有让我不得不使用asio的理由。
是否有必要使用内存池?也是见仁见智的问题,memcache是基于libevent开发的,没有内存池不是也一样很稳定吗?这个问题欢迎大家给出自己的看法
下面是刚写的一个Buffer,有一些ace_message_block的影子,但语义有区别。
#ifndef BUFFER_H
#define BUFFER_H
#include <cstdlib>
#include <cstring>
class Buffer
{
public:
enum
{
BUFFER_TYPE_DATA = 0x01, //数据类型
BUFFER_TYPE_CTRL = 0x02, //控制类型
};
enum
{
DEFAULT_BUFFER = 1024,
};
explicit Buffer(size_t size = DEFAULT_BUFFER,int type = BUFFER_TYPE_DATA);
~Buffer();
//返回Buffer类型
int type();
//设置Buffer类型
void type(int t);
//返回存储空间起始指针
char* base();
//返回存储空间末端指针 + 1
char* end();
//返回未使用空间指针
char* ptr();
//移动数据块指针,如果pos大于0,ptr前移pos;如果pos<0,ptr后移|pos|
void ptr(int pos);
//复制数据,成功返回true,并且移动内部数据块指针;失败返回false
bool copy(const char* p,size_t n);
//返回实际数据块的大小
size_t size();
//返回分配的空间大小,包括未使用空间,space()的值大于等于size()
size_t space();
//返回数据块的总大小,即链表中数据块的大小之和
size_t totalSize();
//返回链表中的下一个Buffer指针
Buffer* next();
//设置下一个Buffer为buf
void next(Buffer* buf);
protected:
private:
int type_;//Buffer类型
char* base_;//指向数据块的起始位置
char* ptr_; //指向未使用空间
size_t space_;//已经分配空间大小
Buffer* next_;//指向的下一个Buffer
};
#endif
#include "Buffer.h"
Buffer::Buffer( size_t size /**//*= DEFAULT_BUFFER*/,int type /**//*= BUFFER_TYPE_DATA*/ )
{
type_ = type;
base_ = (char*)malloc(size);
memset(base_,0,size);
ptr_ = base_;
space_ = size;
next_ = NULL;
}
Buffer::~Buffer()
{
type_ = BUFFER_TYPE_DATA;
free(base_);
base_ = NULL;
ptr_ = NULL;
space_ = 0;
next_ = NULL;
}
int Buffer::type()
{
return type_;
}
void Buffer::type( int t )
{
type_ = t;
}
char* Buffer::base()
{
return base_;
}
char* Buffer::end()
{
return base_ + space_;
}
bool Buffer::copy( const char* p,size_t n )
{
if (space() - size() >= n)
{
memcpy(ptr(),p,n);
ptr((int)n);
return true;
}
else
{
return false;
}
}
size_t Buffer::size()
{
return ptr_ - base_;
}
size_t Buffer::space()
{
return space_;
}
char* Buffer::ptr()
{
return ptr_;
}
void Buffer::ptr( int pos )
{
ptr_ += pos;
}
Buffer* Buffer::next()
{
return next_;
}
void Buffer::next( Buffer* buf )
{
next_ = buf;
}
size_t Buffer::totalSize()
{
size_t size = 0;
for (Buffer* p = this;p != NULL;p = p->next())
{
size += p->size();
}
return size;
}
极为简陋且不完全的使用代码:
#include "../Base/Buffer.h"
int buffer_main(int argc, char* argv[])
{
Buffer* pBuf = new Buffer();
char* pStr = "hello";
pBuf->copy(pStr,strlen(pStr));
size_t len = pBuf->size();
size_t tlen = pBuf->totalSize();
size_t slen = pBuf->space();
delete pBuf;
return 0;
}
TODO:内存池的实现