对于“多线程访问同一个变量是否需要加锁”的研究
对于多线程访问同一变量是否需要加锁的问题,先前大家都讨论过。今天用代码验证了一下之前的猜想:32位CPU与内存的最小交换数据为4字节/次,这也是结构体要对齐4字节的原因。在物理上,CPU对于同一4字节的内存单元,不可能写2个字节的同时,又读了3字节。
测试环境为:
XEON 2CPU*2
Windows7
采用50,50,50线程交叉读写,试验代码如下:
int g_test;
int temp;
BOOL g_bRunning;
DWORD WINAPI thWriteProc1(LPVOID lParam)
{
while(g_bRunning)
{
g_test = 12345678;
Sleep(1);
}
return 0;
}
DWORD WINAPI thWriteProc2(LPVOID lParam)
{
while(g_bRunning)
{
g_test = 13579246;
Sleep(1);
}
return 0;
}
DWORD WINAPI thReadProc(LPVOID lParam)
{
while(g_bRunning)
{
temp = g_test;//读取值
if ( temp != 12345678 && temp != 13579246 )
{
g_bRunning = FALSE;
CString str;
str.Format("read error!%d", temp);
AfxMessageBox(str);
break;
}
Sleep(1);
}
return 0;
}
void CTestMultiyAccessIntDlg::OnButton1()
{
g_bRunning = TRUE;
for ( int i = 0; i < 50; i++ )
{
//创建50个写线程1
CreateThread( NULL, 0, thWriteProc1, NULL, 0, NULL );
}
for ( int i = 0; i < 50; i++ )
{
//创建50个写线程2
CreateThread( NULL, 0, thWriteProc2, NULL, 0, NULL );
}
for ( int i = 0; i < 50; i++ )
{
//创建50个读线程
CreateThread( NULL, 0, thReadProc, NULL, 0, NULL );
}
}
由于是两条语句,执行完第一条之后,别的线程很可能已经修改了g_test的值,如果希望这两条语句执行时,g_test不发生变化,就必须加锁,以保证两条语句执行的整体性。
Lock();
int count = g_test/1024;
int mod= g_test%1024;
UnLock();
如果不加锁,也可以改为先保存到一个临时变量里
int temp = g_test;
int count = temp/1024;
int mod = temp%1024;
[解决办法]
如果我没有弄错的话,float应该也是8字节的。
谢谢楼主对于这个问题的深入研究,学习了~~~
[解决办法]
恩,不错,呵呵~~~谢谢哦~~~
[解决办法]