IOCP多线程服务器和引用计数类

时间:2013-12-15 17:37:10

标签: multithreading reference iocp

我在IOCP服务器上工作(重叠I / O,4个线程,CreateIoCompletionPort,GetQueuedCompletionStatus,WSASend等)。我的目标是发送单个引用计数缓冲区所有连接的套接字。(我遵循了Len Holgate的帖子WSAsend to all connected socket in multithreaded iocp server的建议)。在向所有连接的客户端发送缓冲区后,应将其删除。

这是带有要发送的缓冲区的类

class refbuf
{
 private:
  int m_nLength;
  int m_wsk;
  char *m_pnData; // buffer to send
  mutable int mRefCount;

  public:
  ...

  void grab() const 
   {
          ++mRefCount;
   }

  void release() const
 {
    if(mRefCount > 0);
    --mRefCount;

    if(mRefCount == 0) {delete (refbuf *)this;}
 }  

    ...

char* bufadr() { return m_pnData;}


};

将缓冲区发送到所有套接字

refbuf *refb = new refbuf(4);
...
EnterCriticalSection(&g_CriticalSection);
pTmp1 = g_pCtxtList; // start of linked list with sockets
   while( pTmp1 ) 
   {  
     pTmp2 = pTmp1->pCtxtBack;
     ovl=TakeOvl();     // ovl -struct containing WSAOVERLAPPED 
     ovl->wsabuf.buf=refb->bufadr();// adress m_pnData from refbuf 
     ovl->rcb=refb;  //when GQCS get notification rcb is used to decrease mRefCount
     ovl->wsabuf.len=4;
     refb->grab();     // mRefCount ++
     WSASend(pTmp1->Socket, &(ovl->wsabuf),1,&dwSendNumBytes,0,&(ovl->Overlapped),   NULL);    
     pTmp1 = pTmp2;
  }
   LeaveCriticalSection(&g_CriticalSection);

和4个帖子中的1个

 GetQueuedCompletionStatus(hIOCP, &dwIoSize,(PDWORD_PTR)&lpPerSocketContext, (LPOVERLAPPED *)&lpOverlapped, INFINITE);
 ... 
 lpIOContext = (PPER_IO_CONTEXT)lpOverlapped;
 lpIOContext->rcb->release();  //mRefCount --,if mRefCount reach 0, delete object

我检查了5个连接的客户端,它似乎工作。当GQCS收到所有通知时,mRefCount达到0并执行删除。

我的问题:这种方法是否合适?如果有100个或更多客户端怎么办?当一个线程可以在另一个线程之前删除对象仍然使用它时避免情况吗如何在此scernario中实现原子引用计数?提前谢谢。

1 个答案:

答案 0 :(得分:1)

明显的问题;按重要性顺序......

  1. 您的refbuf类不使用线程安全引用计数操作。使用InterlockedIncrement()
  2. 我认为TakeOvl()每次操作都会获得新的OVERLAPPEDWSABUF结构。
  3. 您的命名可能更好,为什么grab()而不是AddRef()TakeOvl()取得了什么?那些Tmp变量是最重要的东西,它们是“临时的”,所以在更重要的东西之后命名它们。去阅读代码完成。