线程间的通信问题
现在有如下的程序做到线程间的通信,在单核cpu上运行结果正确
可在双核cpu上运行结果会出错,这是怎么回事? 请高手指点一下
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
LPVOID lpParameter // thread data
);
DWORD WINAPI Fun2Proc(
LPVOID lpParameter // thread data
);
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, "tickets ");
if(g_hEvent)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout < < "only instance can run! " < <endl;
return;
}
}
SetEvent(g_hEvent);
Sleep(4000);
CloseHandle(g_hEvent);
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter // thread data
)
{
while(TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
if(tickets> 0)
{
cout < < "thread1 sell ticket : " < <tickets-- < <endl;
}
else
break;
SetEvent(g_hEvent);
}
return 0;
}
DWORD WINAPI Fun2Proc(
LPVOID lpParameter // thread data
)
{
while(TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
if(tickets> 0)
{
cout < < "thread2 sell ticket : " < <tickets-- < <endl;
}
else
break;
SetEvent(g_hEvent);
}
return 0;
}
[解决办法]
需要对全局变量的读写进行序列化处理
tickets
单核中,对一个内存地址的写入不可能同时出现,双核以上就无法保证了
[解决办法]
g_hEvent创建太晚了,应当在在创建线程前初始化
单核系统因为主线程时间片没到,因此虽然CreateThread了,但是Thread没有机会执行, 所以后创建的g_hEvent没有引起错误。但是双核系统上有一个Thread马上就分配到了另一个cpu上和主线程同时执行,此时g_hEvent还没有创建,所以Thread中的WaitSingleObject访问了一个不存在的g_hEvent(在debug模式下g_hEvent的初始化值还不是0, 是0xCCCCCCCC)当然出错啦
[解决办法]
你这个程序有至少三个问题,但是跟单核还是双核是不相干的,单双核我认为是一样的:
(1)就是楼上说的,你的CreateEvent执行太晚。
(2)主线程Sleep再长时间,理论上也不能保证子线程都已经执行完毕。
(3)你仔细分析你的程序,会发现比方说始终都是第一个子线程在运行,当地一个线程运行完后,它并没有调用SetEvent,那么第二个线程会永远等在那里,不会结束。
[解决办法]
应该跟多核有关系