CSocket::OnReceive 同时调用
Posted
技术标签:
【中文标题】CSocket::OnReceive 同时调用【英文标题】:CSocket::OnReceive called concurrently 【发布时间】:2014-02-19 01:09:07 【问题描述】:我有一个奇怪的问题。
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
现在会发生什么:
-
我启动程序,调试器停在断点处
进入日志
调试器在日志中的某些地方跳回断点
这是 OnReceive 的第二个条目
第二次通话完成
第一次通话继续
我的问题:
-
如何同时调用两个 OnReceive
为什么 Mutex 不起作用(由于相同的 threadid?)
我怎样才能有两个具有相同 ThreadID 的执行路径???
当然,我该如何解决这个问题??
请注意,这只发生在我发送大量小消息(
【问题讨论】:
【参考方案1】:好的,我找到了根本原因。在 Log 语句中使用了 Win32 Mutex 和以下等待:
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());
【讨论】:
以上是关于CSocket::OnReceive 同时调用的主要内容,如果未能解决你的问题,请参考以下文章
在 Form.cs 中生成自定义 C# 代码,同时在设计时在 Form1.cs 中删除用户控件
C# WPF中xaml怎么调用.cs中的数据?反过来怎么调用?
Pygame - 在保持单独功能的同时创建具有相同功能的多行
如何解决错误 CS0433:类型“type”同时存在于“Microsoft.UI.Xaml,...”和“Microsoft.UI...”中