我的工程结构:
声明全局的一个变量: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电脑上测试,也是一样的结果,临界区我用的不正确吗?
----------------------------------
没有,但是,当出现一个MessageBox后,而且该MessageBox还没有关掉的时候,就已经又调用了SaveToDB()函数,所以这就是问题
临界区中要放尽可能少的代码和操作,不用说还弹出对话框?还有...不知道干了什么?
----------------------------------------------------------------------------
我想也应该是尽量少放,但是那样的话,我的程序恐怕就要一句一句地写了。弹出对话框不可以吗?还是在临界区中有哪些不能做的事情?
单处理器的系统自动将spin count设为0
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 );
}