看个打破保护原则的例子
#include <stdio.h>
#include <windows.h>
static DWORD WINAPI MyThread( LPVOIDlpParam );
static int num = 20;
int main(int argc, char *argv[])
{
HANDLEhThread[4];
inti;
for( i=0; i<4; i++ )
{
hThread[i]= CreateThread(NULL, 0, MyThread, (LPVOID)i, 0, 0);
}
for( i=0; i<4; i++ )
{
WaitForSingleObject(hThread[i],INFINITE);
}
return0;
}
DWORD WINAPI MyThread( LPVOID lpParam )
{
intindex = (int)lpParam;
printf("id:%d\n", index);
while(1)
{
if(num>0)
{
printf("[id:%d]num = %d\n", index, num);
Sleep(1);
printf("[id:%d]num = %d\n", index, num--);
}else
break;
}
return0;
}
这个程序中,变量 num 就是一个被多个线程共同访问的数据,因为 num 没有被保护,因此,程序输出和预期的会不一样。并且,如果修改 Sleep(1) 中的休眠时间,程序输出又会不同。同样,如果程序在不同的机器上跑,输出也会不一样。造成这种现象的原因就在于,这个程序打破了我们说的线程间共享数据需要被保护的原则。
把 num 用互斥量保护起来以后,bug就被修复了。
#include <stdio.h>
#include <windows.h>
#include "..\..\port\port.h"
static DWORD WINAPI MyThread( LPVOIDlpParam );
static HMutex hMutex;
static int num = 20;
static int Modify(int index);
int main(int argc, char *argv[])
{
HANDLEhThread[4];
inti;
hMutex= mutex_create();
if(hMutex==NULL)
return-1;
for( i=0; i<4; i++ )
{
hThread[i]= CreateThread(NULL, 0, MyThread, (LPVOID)i, 0, 0);
}
for( i=0; i<4; i++ )
{
WaitForSingleObject(hThread[i],INFINITE);
}
mutex_destroy(hMutex);
return0;
}
DWORD WINAPI MyThread( LPVOID lpParam )
{
intindex = (int)lpParam;
printf("id:%d\n", index);
while(1)
{
if(Modify(index)!=0)
break;
}
return0;
}
static int Modify(int index)
{
mutex_lock(hMutex);
if(num>0)
{
printf("[id:%d]num = %d\n", index, num);
Sleep(100);
printf("[id:%d]num = %d\n", index, num--);
}else
{
mutex_unlock(hMutex);
return-1;
}
mutex_unlock(hMutex);
return0;
}
这个程序要被编译,需要port.h头文件,这个头文件是为了多线程程序跨平台而封装的接口文件。