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

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

本文介绍了IOCP 多线程服务器和引用计数类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 IOCP 服务器上工作(重叠 I/O、4 个线程、CreateIoCompletionPort、GetQueuedCompletionStatus、WSASend 等).我的目标是向所有连接的套接字发送单个引用计数缓冲区.(我从这篇文章中遵循了 Len Holgate 的建议 WSA 发送到多线程 iocp 服务器中所有连接的套接字).向所有连接的客户端发送缓冲区后,应将其删除.

I work on IOCP Server (Overlapped I/O , 4 threads, CreateIoCompletionPort, GetQueuedCompletionStatus, WSASend etc). And my goal is to send single reference counted buffer too all connected sockets.(I followed Len Holgate's suggestion from this post WSAsend to all connected socket in multithreaded iocp server) . After sending buffer to all connected clients it should be deleted.

这是要发送缓冲区的类

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;}


};

向所有套接字发送缓冲区

sending buffer to all socket

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 个

and 1 of 4 threads

 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 并执行删除.

i check this with 5 connected clients and it seems to work. When GQCS receives all notifaction, mRefCount reachs 0 and delete is executed.

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

And my questions: is that approach appropriate? What if there will be for example 100 or more clients? Is situation avoided when one thread can delete object before another still use it? How to implement atomic reference count in this scernario? Thanks in advance.

推荐答案

明显问题;按重要性排序...

Obvious issues; in order of importance...

  1. 您的 refbuf 类不使用线程安全的引用计数操作.使用 InterlockedIncrement()
  2. 我假设 TakeOvl() 每次操作都会获得一个新的 OVERLAPPEDWSABUF 结构.
  3. 你的命名可以更好,为什么 grab() 而不是 AddRef()TakeOvl() 取自什么?这些 Tmp 变量是一些东西,最不重要的是它们是临时的",因此以更重要的东西命名它们.去阅读代码完成.
  1. Your refbuf class doesn't use thread safe ref count manipulation. Use InterlockedIncrement() etc.
  2. I assume that TakeOvl() obtains a new OVERLAPPED and WSABUF structure per operation.
  3. Your naming could be better, why grab() rather than AddRef(), what does TakeOvl() take from? Those Tmp variables are something and the least important something is that they're 'temporary' so name them after a more important something. Go Read Code Complete.

这篇关于IOCP 多线程服务器和引用计数类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-21 02:19