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...”中

如何从 .cs 文件 (C#) 调用 JavaScript/jQuery 函数

使用 jquery ajax 在 aspx.cs 文件中调用 web 方法