我有一个奇怪的问题。
void MySocket::OnReceive( int nErrorCode )
{
static CMutex mutex;
static int depth=0;
static int counter=0;
CSingleLock lock(&mutex, true);
Receive(pBuff, iBuffSize-1);
counter++;
depth++; //<-- Breakpoint
log("Onreceive: enter %d %d %d", GetCurrentThreadId(), counter, depth);
.....
Code handling data
depth--;
log("Onreceive: exit %d %d %d", GetCurrentThreadId(), counter, depth);
}
此日志声明中的结果:
02/19/2014 08:33:14:982 [DEBUG] Onreceive Enter: 3200 1 2
02/19/2014 08:34:13:726 [DEBUG] Onreceive Exit : 3200 2 1
02/19/2014 08:32:34:193 [DEBUG] Onreceive Enter: 3200 0 1 <- Log statement was created but interrupted before it was written to disk
02/19/2014 08:34:13:736 [DEBUG] Onreceive Exit : 3200 2 0
现在发生了什么:
我的问题:
请注意,仅当我发送大量小消息(<50Bytes)直到发送块时才会发生这种情况。总计约为500KB / s。如果我在每次发送之后放入睡眠(1)它就不会发生..但是当然会杀死我的传输速度。
答案 0 :(得分:1)
好的,我找到了根本原因。在Log语句中使用Win32 Mutex,并使用以下Wait:
DWORD dwResult = MsgWaitForMultipleObjects(nNoOfHandle, handle, FALSE, dwTimeout, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE|QS_SENDMESSAGE|QS_TIMER);
if (dwResult == WAIT_OBJECT_0 + nNoOfHandle) // new message is in the queue, let's clear
{
MSG Msg;
while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&Msg);
::DispatchMessage(&Msg);
}
}
等待清除Mutex或发布消息。 CSocket在接收数据时将消息发布到线程,并将调用OnReceive。因此,这段代码产生的问题是,在等待互斥锁时,它会处理传入的消息并有效地再次调用OnReceive。
解决此问题的一种方法是阻止CSocket发布更多通知,如下所示:
void MySocket::OnReceive(int nErrorCode)
{
/* Remove FD_READ notifications */
VERIFY(AsyncSelect(FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE));
OldOnReceive(nErrorCode);
/* Restore default notifications */
VERIFY(AsyncSelect());
}