放在VC版没人理,只好放这里了,关于Windows下pipe和自封装类的性能问题

sxbyl 2002-10-11 12:44:40
原帖:http://expert.csdn.net/expert/topic/1085/1085477.xml?temp=.245495

今天我比了一下,居然相差近50倍。虽然文档里说pipe是以内核方式运行的,但我没想到会差这么多。我想是不是我的类设计太不合理了,请大家帮忙看看(很简单)。

我的类名为CPacketBuffer,是基于数据块的存储方式,
主要函数有GetPacket和AddPacket,其中AddPacket在缓冲区满的情况下直接返回FALSE。GetPacket是阻塞的,如果没有可读的数据,就会阻塞。但GetPacket由一个参数hCancelBlockEvent,可以通过设置这个EVENT句柄为信号态来退出阻塞。

原型:
class CPacketBuffer
{
public:
CPacketBuffer();
CPacketBuffer(int nMaxPacketSize, int nMaxPacketCount);
BOOL Create(int nMaxPacketSize, int nMaxPacketCount);
BOOL AddPacket(const BYTE *pPacketBuffer, int nPacketSize=0);
int GetPacket(BYTE *pPacketBuffer, int nBufferSize=0, HANDLE hCancleBlockEvent=NULL);
void Release();
int GetPacketCount()
{
return m_nPacketCount;
}

virtual ~CPacketBuffer();

private:
BYTE *m_pBuffer;
BYTE *m_pBufferUsedHead;
BYTE *m_pBufferUsedTail;
BYTE *m_pBufferTail; //整个缓冲区的结束位置
int m_nMaxPacketSize;
int m_nMaxPacketCount;
HANDLE m_hBufferSemaphore; //空闲缓冲区信号量
CCriticalSection m_csBufferAccess;

int m_nPacketCount; //当前缓冲中的数据包数量

};

以下是几各主要函数:
BOOL CPacketBuffer::Create(int nMaxPacketSize, int nMaxPacketCount)
{
ASSERT(m_pBuffer == NULL && m_hBufferSemaphore == NULL);
try
{
m_nPacketCount=0;
m_nMaxPacketSize=nMaxPacketSize;
m_nMaxPacketCount=nMaxPacketCount;
m_hBufferSemaphore=CreateSemaphore(NULL,0,nMaxPacketCount,NULL);
m_pBuffer=new BYTE[(nMaxPacketSize + sizeof(int)) * nMaxPacketCount];
m_pBufferTail=m_pBuffer + (nMaxPacketSize + sizeof(int)) * nMaxPacketCount;
}
catch(...)
{
}
m_pBufferUsedHead=m_pBuffer;
m_pBufferUsedTail=m_pBuffer;
if(m_pBuffer == NULL || m_hBufferSemaphore == NULL)
return FALSE;
else
return TRUE;
}

BOOL CPacketBuffer::AddPacket(const BYTE *pPacketBuffer, int nPacketSize)
{
if(nPacketSize == 0)
nPacketSize=m_nMaxPacketSize;

CSingleLock l(&m_csBufferAccess);
if(m_nPacketCount == m_nMaxPacketCount) //缓冲区已满
return FALSE;

*(int *)m_pBufferUsedTail=nPacketSize;
memcpy(m_pBufferUsedTail + sizeof(int),pPacketBuffer,nPacketSize);
m_pBufferUsedTail += sizeof(int) + m_nMaxPacketSize;
if(m_pBufferUsedTail == m_pBufferTail) //缓冲区尾部已写满数据,应转到头部
{
m_pBufferUsedTail = m_pBuffer;
}
m_nPacketCount++;
ReleaseSemaphore(m_hBufferSemaphore,1,NULL);
return TRUE;
}

int CPacketBuffer::GetPacket(BYTE *pPacketBuffer, int nBufferSize, HANDLE hCancelBlockEvent)
{
DWORD dwWaitRet;
int nActualSize;
int nRet;
ASSERT(m_nPacketCount >= 0);
if(nBufferSize == 0)
nBufferSize=m_nMaxPacketSize;
if(hCancelBlockEvent == NULL)
dwWaitRet=WaitForSingleObject(m_hBufferSemaphore,INFINITE);
else
{
HANDLE pHandles[2];
pHandles[0]=m_hBufferSemaphore;
pHandles[1]=hCancelBlockEvent;
dwWaitRet=WaitForMultipleObjects(sizeof(pHandles)/sizeof(HANDLE),pHandles,FALSE,INFINITE);
}
if(dwWaitRet == WAIT_OBJECT_0)
{
CSingleLock l(&m_csBufferAccess);
nActualSize=*(int *)m_pBufferUsedHead;
memcpy(pPacketBuffer,m_pBufferUsedHead + sizeof(int),nBufferSize < nActualSize ? nBufferSize:nActualSize);
m_nPacketCount--;
m_pBufferUsedHead += sizeof(int) + m_nMaxPacketSize;
if(m_pBufferUsedHead == m_pBufferTail)
m_pBufferUsedHead = m_pBuffer;
nRet=nActualSize; //返回值为实际数据包大小
}
else
nRet=0; //如果是由于hCancleBlockEvent变为信号态,返回0
return nRet;
}
...全文
56 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
liubear 2002-10-12
  • 打赏
  • 举报
回复
放在这里也没人理,帮你UP一下

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧