Средства разработки приложений


Создание и тестирование многопоточной программы - часть 2


Первый объект изменяет счетчик nCurStep0, второй - nCurStep1. Когда значение счетчика шагов достигнет заданного числа - nStepsAll, объект завершает свою работу. class living_object { static DWORD WINAPI HelperThreadProc(LPVOID p); public: living_object(); virtual void run() {}; virtual ~living_object() {}; }; extern HANDLE hStart; extern CRITICAL_SECTION cs; extern int total_threads; extern DWORD endTick; living_object::living_object() { DWORD threadID; if(!CreateThread(NULL, 0, HelperThreadProc, (LPVOID)this, 0, &threadID)) printf("GetLastError: %d\n", GetLastError()); } DWORD WINAPI living_object::HelperThreadProc(LPVOID p) { EnterCriticalSection(&cs); total_threads++; LeaveCriticalSection(&cs); WaitForSingleObject(hStart, INFINITE); ((living_object*)p)->run(); EnterCriticalSection(&cs); total_threads--; endTick=GetTickCount(); LeaveCriticalSection(&cs); return 0; } Листинг 2. Код класса базового активного объекта living_object .

Тренер, бегущий рядом с бегунами, имеет следующий код (Листинг 3): #include "living_object.h" class CDat; class PrnCurStep : public living_object { public: PrnCurStep(CDat *d); virtual ~PrnCurStep(); void run(); private: CDat *pCDat; long lTmp0; long lTmp1; }; PrnCurStep::PrnCurStep(CDat *d): living_object() { pCDat = d; lTmp0= lTmp1= 0; } PrnCurStep::~PrnCurStep() { } void PrnCurStep::run() { while (pCDat->nStepsAll != pCDat->nCurStep0) { // printf("%d %d\n", pCDat->nCurStep0, pCDat->nCurStep1); ///* if (lTmp0 != pCDat->nCurStep0 lTmp1 != pCDat->nCurStep1) { printf("%d %d\n", pCDat->nCurStep0, pCDat->nCurStep1); lTmp0 = pCDat->nCurStep0; lTmp1 = pCDat->nCurStep1; } // Sleep(0); //*/ } } Листинг 3. Код класса "тренер".

В рамках метода run "тренер" на каждой итерации цикла выводит на консоль текущие значения счетчика циклов обоих бегунов.

Тестирование. Запустив программу, моделирующую бегунов, мы получим результат, который показан на рис.1.





Начало  Назад  Вперед