vc++深入详解中的多线程例子,在多核CPU下出错分析。
#include <WINDOWS.H>#include <IOSTREAM>using namespace std;/* * 在单核单CPU下正常运行 */DWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter);int tickets = 100;HANDLE g_hEvent;void main(){ HANDLE hThread1,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); CloseHandle(g_hEvent);}DWORD WINAPI Fun1Proc(LPVOID lpParameter){ while(TRUE) { WaitForSingleObject(g_hEvent,INFINITE); //ResetEvent(g_hEvent); if (tickets > 0) { Sleep(1); cout<<"Thread1 sell ticket:"<<tickets--<<endl; } else break; SetEvent(g_hEvent); } return 0;}DWORD WINAPI Fun2Proc(LPVOID lpParameter){ while(TRUE) { WaitForSingleObject(g_hEvent,INFINITE); //ResetEvent(g_hEvent); if (tickets > 0) { Sleep(1); cout<<"Thread2 sell ticket:"<<tickets--<<endl; } else break; SetEvent(g_hEvent); } return 0;}
Thread1 sell ticket:9
Thread2 sell ticket:8
Thread1 sell ticket:Th7r
ead2 sell ticket:6
Thread1 sell ticket:5
Thread2 sell ticket:Th4re
ad1 sell ticket:3
Thread2 sell ticket:2
Thread1 sell ticket:Thr1e
ad2 sell ticket:0
Press any key to continue
结果分析,在运行线程时g_hEvent可能未创建。
代码改为如下变正常了。
#include <WINDOWS.H>#include <IOSTREAM>using namespace std;/* * 在单核单CPU下正常运行 */DWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter);int tickets = 100;HANDLE g_hEvent;void main(){ g_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); SetEvent(g_hEvent); HANDLE hThread1,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); CloseHandle(g_hEvent);}DWORD WINAPI Fun1Proc(LPVOID lpParameter){ while(TRUE) { WaitForSingleObject(g_hEvent,INFINITE); //ResetEvent(g_hEvent); if (tickets > 0) { Sleep(1); cout<<"Thread1 sell ticket:"<<tickets--<<endl; } else break; SetEvent(g_hEvent); } return 0;}DWORD WINAPI Fun2Proc(LPVOID lpParameter){ while(TRUE) { WaitForSingleObject(g_hEvent,INFINITE); //ResetEvent(g_hEvent); if (tickets > 0) { Sleep(1); cout<<"Thread2 sell ticket:"<<tickets--<<endl; } else break; SetEvent(g_hEvent); } return 0;}