Я работаю на сервере IOCP (перекрывающийся ввод-вывод, 4 потока, CreateIoCompletionPort, GetQueuedCompletionStatus, WSASend и т. Д.). И моя цель - отправить единый буфер с подсчетом ссылок для всех подключенных сокетов. (Я последовал предложению Лена Холгейта из этого сообщения WSAsend на все подключенные сокеты на многопоточном сервере iocp). После отправки буфера всем подключенным клиентам его следует удалить.
это класс с буфером для отправки
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);
и 1 из 4 потоков
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 и более? Можно ли избежать ситуации, когда один поток может удалить объект, прежде чем другой все еще будет его использовать? Как реализовать атомарный счетчик ссылок в этом сценарии? Заранее спасибо.
grab
и комментировать то, что он делает, просто назовите егоaddRef
илиincRefCount
. - person usr   schedule 16.12.2013