当我们使用内核对象(如事件内核对象)进行2线程同步的时候,是否会发生如下情况:
两个线程都是第一次启动时候,同时获取到内核对象的使用权?我觉得会发生,上代码:
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int tickets=100;
HANDLE g_hEvent;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
SetEvent(g_hEvent);
Sleep(4000);
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter
)
{
while(TRUE)
{ //Sleep(10); 不加此行代码时候,结果经常会出现 :
//thread2 sell ticket 100
//thread1 sell ticket 99
WaitForSingleObject(g_hEvent,INFINITE);
if(tickets>0)
{ Sleep(1);
cout<<"thread1 sell ticket :"<<tickets--<<endl;
}
else
break;
}
return 0;
}
DWORD WINAPI Fun2Proc(
LPVOID lpParameter
)
{
while(TRUE)
{ WaitForSingleObject(g_hEvent,INFINITE);
if(tickets>0)
{
cout<<"thread2 sell ticket :"<<tickets--<<endl;
}
else
break;
}
return 0;
}
结果有两种:
1) thread2 sell ticket :100
2) thread2 sell ticket :100
thread1 sell ticket :99
按照我的分析,出现结果2的原因为:因我的电脑是双CPU的,所以第一次两个线程可能同时都得到事件内核对象处于信号状态,于是两个线程都获取到了对WaitForSingleObject函数一下的代码的使用权,但是由于线程1的Sleep(1)的存在,所以线程2先完成了cout<<"thread2 sell ticket :"<<tickets--<<endl;这行代码的执行.所以线程2打印100,之后线程1睡眠过后,接着执行cout<<"thread1 sell ticket :"<<tickets--<<endl;这行代码.(因为是自动重置,所以内核对象会一直处于没信号状态,两个线程都不能接着打印!)
不知道我的分析对不对呢?我想问的是,在双CPU情况下,两个线程是否有可能都同时获取到信号?