当线程之间需要用到共同的变量时,不希望某一个线程使用时,被其它线程给调用,就需要互斥锁来保证共享资源该线程使用完后,再给其它线程使用;
典型例子:
由于线程是获取到操作系统分配的CPU时间片是才会执行,所以单CPU的情况下,多线程同步其实并非同步,当其中一个线程1执行的时候,可能会中途跳至线程2执行,这就会导致,线程1在使用某一共享资源时,还没来得急用,就已经被线程2使用,这就会引发很多问题;
int iCount = 0;
void main()
{
HANDLE thread1,thread2;
thread1 = CreateThread(NULL,0,ThreadPro1,NULL,0,NULL);
thread2 = CreateThread(NULL,0,ThreadPro2,NULL,0,NULL);
CloseHandle(thread1);
CloseHandle(thread2);
system("pause");
}
WORD WINAPI ThreadPro1(LPVOID lpParameter)
{
while(TRUE)
{
if(iCount<10) cout<<"Thread1: The Count is "<<iCount++<<endl;
else break;
}
return 0;
}
WORD WINAPI ThreadPro2(LPVOID lpParameter)
{
while(TRUE)
{
if(iCount<10) cout<<"Thread2: The Count is "<<iCount++<<endl;
else break;
}
return 0;
}
问题分析:
由于线程Thread1和线程Thread2都在用使用全局变量iCount,假如当iCount 等于9时,线程Thread1判断iCount小于10,进入if语内,此时线程Thread1的时间片结束,就会分配到线程Thread2,此时iCount依旧是9所以线程Thread2继续输出,iCount变为10,当线程Thread1重获时间片时,iCount的判断已经跳过,所以继续输出iCount,此时iCount已经为10,不再小于10,导致结果出错;
互斥锁:
互斥锁就像一把钥匙,如果进入房间的人,没出来,外面的人没有钥匙就不能进去,必须等着拿到这把钥匙的归还钥匙,并获得这把钥匙才能进入。多线程访问统一变量时,当某一线程用完这一变量后,其它线程才能使用这一变量;
int iCOunt = 0;
HANDLE pMutex;
void main()
{
pMutex = CreateMutex(NULL,FALSE,NULL);
HANDLE handle1,handle2;
handle1 = CreateThread(NULL,0,ThreadPro1,NULL,0,NULL);
handle2 = CreateThread(NULL,0,ThreadPro2,NULL,0,NULL);
CloseHandle(handle1);
CloseHandle(handle2);
system("pause");
}
DWORD WINAPI ThreadPro1(LPVOID lpParameter)
{
While(TRUE)
{
WaitForSingleObject(pMutex,INFINITE);
if(iCount<10) cout<<"Thread1: The Count is "<<iCount++<<endl;
else break;
ReleaseMutex(pMutex);
}
return 0;
}
DWORD WINAPI ThreadPro2(LPVOID lpParameter)
{
while(TRUE)
{
WaitForSingleObject(pMutex,INFINITE);
if(iCount < 10) cout<<"Thead1: The Count is "<<iCount++<<endl;
else break;
ReleaseMutex(pMutex);
}
return 0;
}
CreateMutex用于创建互斥体,就是俗话说的一把锁,WaitForSingleObject就是检查这把锁被拿没有,如果被拿了,就一直等着这把锁放回来,没拿就拿到这把锁进门,开始干自己事,ReleaseMutex就是在房间内干完事后,出来把锁放回去,给别人用。这样,在线程使用共享资源时,如果不想同时使用,就可以使用互斥锁,把不想同时使用的关键代码锁上。