Threads Example
C++ can deal with mutiple threads. Suppose we have two guys selling tickets at the same time. The programme is as follows:
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int tickets = 40;
HANDLE g_hEvent;
CRITICAL_SECTION cs;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1 = CreateThread(NULL, 0, &Fun1Proc, NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, &Fun2Proc, NULL, 0, NULL);
InitializeCriticalSection(&cs);
g_hEvent = CreateEvent(NULL, FALSE, FALSE, L"qqq");
if (g_hEvent)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
cout << "only one instance is running" << endl;
return;
}
}
SetEvent(g_hEvent);
//Sleep(10000);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
DeleteCriticalSection(&cs);
CloseHandle(g_hEvent);
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
cout << "enter Fun1Proc()!!\n";
while (TRUE)
{
WaitForSingleObject(g_hEvent, INFINITE);
SetEvent(g_hEvent);
if (tickets>0)
{
Sleep(300);
if (tickets > 0)
{
EnterCriticalSection(&cs);
cout << "thread1 sells ticket:" << tickets-- << endl;
LeaveCriticalSection(&cs);
}
else
{
break;
}
}
else {
break;
}
}
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
cout << "enter Fun2Proc()!!\n";
while (TRUE)
{
WaitForSingleObject(g_hEvent, INFINITE);
SetEvent(g_hEvent);
if (tickets>0)
{
Sleep(1000);
if (tickets > 0)
{
EnterCriticalSection(&cs);
cout << "thread2 sells ticket:" << tickets-- << endl;
LeaveCriticalSection(&cs);
}
else
{
break;
}
}
else {
break;
}
}
return 0;
}
A question then arises----what if there are more than 2 guys selling ticket, actually we have 10? I certainly don't want to copy DWORD WINAPI Fun1Proc(LPVOID lpParameter) again and again. A solution is that we define them in one class, which has the function of selling ticket. Each instantiation of the class is a guy who can sell tickets. Their shared event g_hEvent activates each one to sell tickets.
#include <windows.h>
#include <iostream>
using namespace std;
class FunThread{
public:
int T;
static int tickets;
int ID;
static int Num;
static HANDLE g_hEvent;
static CRITICAL_SECTION cs;
HANDLE hThread;
FunThread(int t)
{
T = t;
Num = Num + 1;
ID = Num;
//InitializeCriticalSection(&cs);
hThread = CreateThread(NULL, 0, FunThread::WorkerThread, this, 0, NULL);
}
~FunThread()
{
CloseHandle(hThread);
//DeleteCriticalSection(&cs);
}
static DWORD WINAPI WorkerThread(_In_ LPVOID lpParameter)
{
HRESULT hr = S_OK;
FunThread* pThis = static_cast<FunThread *>(lpParameter);
hr = pThis->WorkerThread();
return SUCCEEDED(hr) ? 0 : 1;
}
HRESULT WorkerThread()
{
EnterCriticalSection(&cs);
cout << "Enter thread " << ID << "!!\n";
LeaveCriticalSection(&cs);
while (TRUE)
{
WaitForSingleObject(g_hEvent, INFINITE);
SetEvent(g_hEvent);
if (tickets>0)
{
Sleep(T);
if (tickets > 0)
{
EnterCriticalSection(&cs);
cout << "thread " << ID << " sells ticket:" << tickets-- << endl;
LeaveCriticalSection(&cs);
}
else
{
break;
}
}
else {
break;
}
}
return 0;
}
};
int FunThread::tickets = 30;
int FunThread::Num = 0;
HANDLE FunThread::g_hEvent = CreateEvent(NULL, FALSE, FALSE, L"qqq");
CRITICAL_SECTION FunThread::cs;
void main()
{
FunThread* a = new FunThread(1000);
FunThread* b = new FunThread(200);
InitializeCriticalSection(&FunThread::cs);
if (FunThread::g_hEvent)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
cout << "only one instance is running" << endl;
return;
}
}
SetEvent(FunThread::g_hEvent);
WaitForSingleObject(a->hThread, INFINITE);
WaitForSingleObject(b->hThread, INFINITE);
CloseHandle(FunThread::g_hEvent);
DeleteCriticalSection(&FunThread::cs);
}