作者:
www.shnenglu.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:內存池的實現