📄 threads.cpp
字号:
#include "stdafx.h"
#include "Threads.h"
#include "facebase.h"
#include <afxtempl.h>
#include <float.h>
#include "image.h"
//#include "cv.h"
//#include "HMMDemo.h"
//#include "FaceBase.h"
//#include "direct.h"
#include "multiprocdiv.h"
#define NONE_FINISH_WORK -1
#define BRAKE_WORK -2
//#define PRIOR //
#define PRIOR
#define CHECK_TRAIN_FOR_BREAK(mac_thrArr,mac_thrParams,mac_numProc) \
if( thrFinishWork == BRAKE_WORK ) { \
int mac_i; \
POSITION pos; \
for( mac_i = 0; mac_i < mac_numProc; mac_i ++ ) { \
if( mac_thrParams[mac_i].working == true ) { \
mac_thrParams[mac_i].doNext = false; \
ResumeThread( mac_thrArr[mac_i] ); \
Sleep(50); \
} \
} \
for( pos = base.GetPersonList().GetHeadPosition(); pos; ) \
{ \
CPerson* person = base.GetPersonList().GetNext( pos ); \
person->SetTrainFlag( false ); \
} \
Sleep( 5000 ); \
for( mac_i = 0; mac_i < mac_numProc; mac_i ++ ) { \
if( mac_thrParams[mac_i].working == true ) { \
char buf[256]; \
_RPT1( _CRT_WARN, "Terminating thread #%d\n", mac_i ); \
if( !TerminateThread( mac_thrArr[mac_i], 1 ) ) { \
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 256, 0 ); \
_RPT1( _CRT_WARN, "TerminateThread returned: %s\n", buf ); \
} \
else { \
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 256, 0 ); \
_RPT1( _CRT_WARN, "TerminateThread returned: %s\n", buf ); \
} \
WaitForSingleObject( mac_thrArr[mac_i], 3000 ); \
} \
} \
base.DeleteHMMInfo(); \
CloseHandle( g_hevtWakeUpControlThread ); \
DeleteCriticalSection( &g_critSect ); \
hCtrlTrainThread = 0; \
trainParam.frame->EnableItemsAfterTrain(); \
ExitThread(0); \
}
#define CHECK_TRAIN_FOR_BREAK1(mac_thrArr,mac_thrParams,mac_numProc) \
if( thrFinishWork == BRAKE_WORK ) { \
int mac_i; \
for( mac_i = 0; mac_i < mac_numProc; mac_i ++ ) { \
if( mac_thrParams[mac_i].working == true ) { \
mac_thrParams[mac_i].doNext = false; \
ResumeThread( mac_thrArr[mac_i] ); \
} \
} \
Sleep( 5000 ); \
for( mac_i = 0; mac_i < mac_numProc; mac_i ++ ) { \
if( mac_thrParams[mac_i].working == true ) { \
char buf[256]; \
_RPT1( _CRT_WARN, "Terminating thread #%d\n", mac_i ); \
if( !TerminateThread( mac_thrArr[mac_i], 1 ) ) { \
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 256, 0 ); \
_RPT1( _CRT_WARN, "TerminateThread returned: %s\n", buf ); \
} \
else { \
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 256, 0 ); \
_RPT1( _CRT_WARN, "TerminateThread returned: %s\n", buf ); \
} \
WaitForSingleObject( mac_thrArr[mac_i], 30 ); \
} \
} \
CloseHandle( g_hevtWakeUpControlThread ); \
DeleteCriticalSection( &g_critSect ); \
hCtrlTrainThread = 0; \
ExitThread(0); \
}
struct TrainThreadParams {
int threadNum;
CPerson* person;
int doNext;
HANDLE hThread;
bool working;
};
HANDLE g_hevtWakeUpControlThread;
CRITICAL_SECTION g_critSect;
DWORD dwCtrlTrainThread;
HANDLE hCtrlTrainThread;
volatile int thrFinishWork;
StartTrainParams trainParam;
//DWORD WINAPI ThreadProc(
// LPVOID lpParameter // thread data
//);
DWORD trainFunc( LPVOID param )
{
TrainThreadParams* thrParams = (TrainThreadParams*)param;
int threadNum = thrParams->threadNum;
HANDLE hThread = thrParams->hThread;
CPerson* person;
int anotherThrBlocksVar;
InterlockedExchange( (long*)&(thrParams->working), (int)true );
while( thrParams->doNext )
{
person = thrParams->person;
_RPT1( _CRT_WARN, "Thread #%d begins\n", threadNum );
EnterCriticalSection( &g_critSect );
person->LoadRest();
LeaveCriticalSection( &g_critSect );
person->TrainHMM();
person->UnloadRest();
if( !thrParams->doNext ) {
break;
}
_RPT1( _CRT_WARN, "Thread #%d ends\n", threadNum );
EnterCriticalSection( &g_critSect );
thrParams->doNext = false;
anotherThrBlocksVar = true;
while( anotherThrBlocksVar )
{
if( thrFinishWork == NONE_FINISH_WORK ) {
thrFinishWork = threadNum;
anotherThrBlocksVar = false;
}
else {
LeaveCriticalSection( &g_critSect );
Sleep(0);
EnterCriticalSection( &g_critSect );
}
}
_RPT1( _CRT_WARN, "Thread #%d sets event\n", threadNum );
SetEvent( g_hevtWakeUpControlThread );
LeaveCriticalSection( &g_critSect );
_RPT1( _CRT_WARN, "Thread #%d suspends\n", threadNum );
SuspendThread( hThread );
Sleep(0);
_RPT1( _CRT_WARN, "Thread #%d resumes\n", threadNum );
} // while( thrParams->doNext )
_RPT1( _CRT_WARN, "Thread #%d finishes\n", threadNum );
InterlockedExchange( (long*)&(thrParams->working), (int)false );
return 0;
} // trainFunc
DWORD ctrlTrainThreadFunc( LPVOID param )
{
SYSTEM_INFO sysInfo;
int numProc;
int i;
DWORD dwTrainThread[32];
HANDLE hTrainThread[32];
TrainThreadParams thrParams[32];
DWORD affMask = 0;
POSITION pos;
CPerson* person;
InitializeCriticalSection( &g_critSect );
g_hevtWakeUpControlThread = CreateEvent( 0, true, false, "WakeUpCtrlTrainThread" );
GetSystemInfo( &sysInfo );
numProc = sysInfo.dwNumberOfProcessors;
numProc = 32;
if( numProc > 32 ) {
CloseHandle( g_hevtWakeUpControlThread );
DeleteCriticalSection( &g_critSect );
hCtrlTrainThread = 0;
return 0;
}
trainParam.frame->DisableItemsForTrain();
if( numProc == 1 )
{
// Single processor code
CHMMDemoDoc* doc = ( (StartTrainParams*)param )->doc;
if( !doc )
return 0;
CFaceBase& base = doc->GetFaceBase();
base.TrainAll( ( (StartTrainParams*)param )->flag );
}
else {
// Multiple processor code
CHMMDemoDoc* doc = ( (StartTrainParams*)param )->doc;
if( !doc )
ExitThread(0);
CFaceBase& base = doc->GetFaceBase();
affMask = 0;
for( i = 0; i < numProc; i ++ )
{
affMask |= ( 1 << i );
}
for( i = 0; i < numProc; i ++ )
{
thrParams[i].threadNum = i;
thrParams[i].working = true;
hTrainThread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)trainFunc, &(thrParams[i]), CREATE_SUSPENDED, &(dwTrainThread[i]) );
thrParams[i].hThread = hTrainThread[i];
thrParams[i].doNext = false;
PRIOR SetThreadPriority( hTrainThread[i], THREAD_PRIORITY_BELOW_NORMAL );
//SetThreadAffinityMask( hTrainThread[i], affMask );
//SetThreadIdealProcessor( hTrainThread[i], (DWORD)i );
}
thrFinishWork = NONE_FINISH_WORK;
ResetEvent( g_hevtWakeUpControlThread );
for( i = 0, pos = base.GetPersonList().GetHeadPosition(); pos; )
{
person = base.GetPersonList().GetNext(pos);
_RPT2( _CRT_WARN, "%s %d\n", "pos = ", (int)pos );
if( (( (StartTrainParams*)param )->flag == TRAIN_UNTRAINED) && person->IsTrained() ) continue;
EnterCriticalSection( &g_critSect );
_RPT1( _CRT_WARN, "Giving execute to thread #%d\n", i );
thrParams[i].person = person;
thrParams[i].doNext = true;
LeaveCriticalSection( &g_critSect );
_RPT1( _CRT_WARN, "Resuming thread #%d\n", i );
ResumeThread( hTrainThread[i] );
i ++;
if( i == numProc ) {
break;
}
}
if( i != numProc ) {
while( i > 0 ) {
WaitForSingleObject( g_hevtWakeUpControlThread, INFINITE );
CHECK_TRAIN_FOR_BREAK( hTrainThread, thrParams, numProc );
_RPT1( _CRT_WARN, "Main thread gets last event from thread #%d\n", thrFinishWork );
EnterCriticalSection( &g_critSect );
ResetEvent( g_hevtWakeUpControlThread );
thrParams[ thrFinishWork ].doNext = false;
_RPT1( _CRT_WARN, "Resuming thread #%d\n", thrFinishWork );
ResumeThread( hTrainThread[ thrFinishWork ] );
thrFinishWork = NONE_FINISH_WORK;
i --;
LeaveCriticalSection( &g_critSect );
}
} // if( i == numProc )
else {
i = base.GetPersonList().GetCount() - numProc;
while( i > 0 ) {
WaitForSingleObject( g_hevtWakeUpControlThread, INFINITE );
CHECK_TRAIN_FOR_BREAK( hTrainThread, thrParams, numProc );
_RPT0( _CRT_WARN, "Main thread gets event\n" );
EnterCriticalSection( &g_critSect );
ResetEvent( g_hevtWakeUpControlThread );
person = base.GetPersonList().GetNext(pos);
_RPT1( _CRT_WARN, "pos = %d\n", (int)pos );
while( pos && person->IsTrained() ) {
if( (( (StartTrainParams*)param )->flag != TRAIN_UNTRAINED) ) {
person = base.GetPersonList().GetNext(pos);
i --;
}
}
if( person ) {
_RPT1( _CRT_WARN, "Giving execute to thread #%d\n", thrFinishWork );
thrParams[ thrFinishWork ].person = person;
thrParams[ thrFinishWork ].doNext = true;
_RPT1( _CRT_WARN, "Resuming thread #%d\n", thrFinishWork );
ResumeThread( hTrainThread[ thrFinishWork ] );
thrFinishWork = NONE_FINISH_WORK;
i --;
}
LeaveCriticalSection( &g_critSect );
_RPT1( _CRT_WARN, "i = %d\n", i );
//WaitForSingleObject( g_hevtWakeUpControlThread, INFINITE );
} // while( i > 0 )
for( i = 0; i < numProc; i ++ ) {
int thrNum;
DWORD resumeRes;
WaitForSingleObject( g_hevtWakeUpControlThread, INFINITE );
CHECK_TRAIN_FOR_BREAK( hTrainThread, thrParams, numProc );
_RPT1( _CRT_WARN, "Main thread gets last event from thread #%d\n", thrFinishWork );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -