我正在看别人的代码,其中一段(工作者线程)如下:
DWORD WINAPI CIOCPServer::_WorkerThreadProc(LPVOID lpParam)
{
#ifdef _DEBUG
::OutputDebugString(" WorkerThread 启动... \n");
#endif // _DEBUG CIOCPServer *pThis = (CIOCPServer*)lpParam; CIOCPBuffer *pBuffer;
DWORD dwKey;
DWORD dwTrans;
LPOVERLAPPED lpol;
while(TRUE)
{
// 在关联到此完成端口的所有套节字上等待I/O完成
BOOL bOK = ::GetQueuedCompletionStatus(pThis->m_hCompletion,
&dwTrans, (LPDWORD)&dwKey, (LPOVERLAPPED*)&lpol, WSA_INFINITE); if(dwTrans == -1) // 用户通知退出
{
#ifdef _DEBUG
::OutputDebugString(" WorkerThread 退出 \n");
#endif // _DEBUG
::ExitThread(0);
} pBuffer = CONTAINING_RECORD(lpol, CIOCPBuffer, ol);
int nError = NO_ERROR;
if(!bOK) // 在此套节字上有错误发生
{
SOCKET s;
if(pBuffer->nOperation == OP_ACCEPT)
{
s = pThis->m_sListen;
}
else
{
if(dwKey == 0)
break;
s = ((CIOCPContext*)dwKey)->s;
}
DWORD dwFlags = 0;
if(!::WSAGetOverlappedResult(s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags))
{
nError = ::WSAGetLastError();
}
}
pThis->HandleIO(dwKey, pBuffer, dwTrans, nError);
}#ifdef _DEBUG
::OutputDebugString(" WorkerThread 退出 \n");
#endif // _DEBUG
return 0;
}其中pBuffer是per-IO数据,HandleIO处理完成的请求,投递新的请求,释放完成的per-I/O和per-handl数据。我的问题是GetQueuedCompletionStatus的返回值不太了解,对以下段代码不太理解:
if(!bOK)
{
这里整段的代码不太理解,各位高手帮忙详细解释一下啊 !!!
}
拜托了,刚开始看完成端口,郁闷了一下午了!!!
DWORD WINAPI CIOCPServer::_WorkerThreadProc(LPVOID lpParam)
{
#ifdef _DEBUG
::OutputDebugString(" WorkerThread 启动... \n");
#endif // _DEBUG CIOCPServer *pThis = (CIOCPServer*)lpParam; CIOCPBuffer *pBuffer;
DWORD dwKey;
DWORD dwTrans;
LPOVERLAPPED lpol;
while(TRUE)
{
// 在关联到此完成端口的所有套节字上等待I/O完成
BOOL bOK = ::GetQueuedCompletionStatus(pThis->m_hCompletion,
&dwTrans, (LPDWORD)&dwKey, (LPOVERLAPPED*)&lpol, WSA_INFINITE); if(dwTrans == -1) // 用户通知退出
{
#ifdef _DEBUG
::OutputDebugString(" WorkerThread 退出 \n");
#endif // _DEBUG
::ExitThread(0);
} pBuffer = CONTAINING_RECORD(lpol, CIOCPBuffer, ol);
int nError = NO_ERROR;
if(!bOK) // 在此套节字上有错误发生
{
SOCKET s;
if(pBuffer->nOperation == OP_ACCEPT)
{
s = pThis->m_sListen;
}
else
{
if(dwKey == 0)
break;
s = ((CIOCPContext*)dwKey)->s;
}
DWORD dwFlags = 0;
if(!::WSAGetOverlappedResult(s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags))
{
nError = ::WSAGetLastError();
}
}
pThis->HandleIO(dwKey, pBuffer, dwTrans, nError);
}#ifdef _DEBUG
::OutputDebugString(" WorkerThread 退出 \n");
#endif // _DEBUG
return 0;
}其中pBuffer是per-IO数据,HandleIO处理完成的请求,投递新的请求,释放完成的per-I/O和per-handl数据。我的问题是GetQueuedCompletionStatus的返回值不太了解,对以下段代码不太理解:
if(!bOK)
{
这里整段的代码不太理解,各位高手帮忙详细解释一下啊 !!!
}
拜托了,刚开始看完成端口,郁闷了一下午了!!!
if(!bOK)
{
这里整段的代码不太理解,各位高手帮忙详细解释一下啊 !!!
}
麻烦你给我解释一下,这里的
if()
...... //1
else
...... //2
if(!::WSAGetOverlappedResult(s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags)) //3
{
nError = ::WSAGetLastError();
}
这三处注释我是在不明白,麻烦您帮我解释一下。
CIOCPBuffer的第一个字段就是个overlap结构,也就是CIOCPBuffer这个结构体的首地址,把这个首地址提交,这样在GetQueuedCompletionStatus返回时就能获得CIOCPBuffer表示的结构了,是充分利用这个技巧才能够拓宽表示内容
if(!bOK) // 在此套节字上有错误发生
{
SOCKET s;
if(pBuffer->nOperation == OP_ACCEPT) //1.这里是第一处不明白,为什么这样,得到s做什么
{
s = pThis->m_sListen;
}
else
{
if(dwKey == 0) //2.这里又是为什么:1.用意和在;2.为什么又要得到s
break;
s = ((CIOCPContext*)dwKey)->s;
}
DWORD dwFlags = 0;
if(!::WSAGetOverlappedResult(s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags))
{ //3.对这个得到的s调用WSAGetOverlappedResult作用。 nError = ::WSAGetLastError();
}
}请高手回答我的三个问题
io投递后只不过缩投递的缓冲区会被系统锁定,这也就需要很大的内存,之所以说它比重叠io多占用系统资源
锁定谁的缓冲区?2.完成例程、完成端口提供了比较好的解决方案,只不过对于完成例程
来说,初次使用的朋友可能感觉不是很好用,其实它也可以实现很高的性能解决方案,因为他本身就是通过用户APC来
实现;最后一个是完成端口通知,相对于完成例程来说,它建立多工作线程来监视多个socket事件更加容易。
这个完成端口和完成例程不是一个概念吗?
2.不知道这是谁写的,要不你问问写这段话的人吧。相关重叠I/O的几种应用方式,我已经在你的贴子当中进行了列举,这里就不再重复。