我的工程结构:
声明全局的一个变量:CRITICAL_SECTION m_crtDev;
系统一启动就初始化:InitializeCriticalSection( &m_crtDev );
在主对话框的OnInitDialog中,启动服务器用监听用于客户端来连接在客户端连接上来之后,开始收数据:
void CSocketClient::OnReceive(int nErrorCode) 
{
int i;
unsigned char szTmp[1024*200+5];
CString strLogSys; EnterCriticalSection( &g_Vars.m_crtDev );   // 进入临界区
memset( szTmp, 0, sizeof(szTmp) );
i = Receive( szTmp, sizeof(szTmp) - 1 );
          ...
          if ( szTmp[0] == 0 )
             GetData(szTmp);// 处理收到的数据
          else
             SaveToDB( szTmp );
         ...
LeaveCriticalSection( &g_Vars.m_crtDev );
CSocketClient::OnReceive(nErrorCode);
}// 处理数据
void CSocketClient::GetData(unsigned char *p) 
{
   ...
   if ( MessageBox( "确定要继续吗?", MB_ICONQUESTION|MB_YESNO ) != IDYES )
      return;
   ...
}问题就在这之中,不知道是怎么回事:
在收到数据之后,我调用临界区函数,希望每次同时只处理一组数据,但是,当在GetData中出现对话框等待用户确认的时候,发现在收到数据后,执行已经超过了   // 进入临界区 这一行,即也已经进入临界区,这不可能的事情竟然发生了,怎么回事?
我的电脑有2个cpu,于是我就拿这个程序到别人的单cpu电脑上测试,也是一样的结果,临界区我用的不正确吗?

解决方案 »

  1.   

    同时出现两个以上 MessageBox ?
      

  2.   

    同时出现两个以上 MessageBox ?
    ----------------------------------
    没有,但是,当出现一个MessageBox后,而且该MessageBox还没有关掉的时候,就已经又调用了SaveToDB()函数,所以这就是问题
    临界区中要放尽可能少的代码和操作,不用说还弹出对话框?还有...不知道干了什么?
    ----------------------------------------------------------------------------
    我想也应该是尽量少放,但是那样的话,我的程序恐怕就要一句一句地写了。弹出对话框不可以吗?还是在临界区中有哪些不能做的事情?
      

  3.   

    MessageBox尽量只在CWnd类中用啊,否则出问题神不知鬼不觉,我的经验如此……
      

  4.   

    哦,那我准备去掉一些选项,这样就不用MessageBox了,只是少了一个人性化的交互等一下先试试再说
      

  5.   

    用InitializeCriticalSectionAndSpinCount
    单处理器的系统自动将spin count设为0
      

  6.   

    临界区中要放尽可能少的代码和操作,如果中间的代码执行时间较长,建议采用mutex此外,你EnterCriticalSection的位置应如下:
    void CSocketClient::GetData(unsigned char *p) 
    {
       EnterCriticalSection( &g_Vars.m_crtDev );   // 进入临界区
      ...
       LeaveCriticalSection( &g_Vars.m_crtDev );
       if ( MessageBox( "确定要继续吗?", MB_ICONQUESTION|MB_YESNO ) != IDYES )
          return;
      EnterCriticalSection( &g_Vars.m_crtDev );   // 进入临界区
      ...
      LeaveCriticalSection( &g_Vars.m_crtDev );
       }
      

  7.   

    你干嘛不把CriticalSection用C++类给封装一下呢,这样在构造函数自动进入,析构里自动退出。多省事呀。