📄 threadcollection.cpp
字号:
#include "stdafx.h"
#include "math.h"
#include "ThreadCompete.h"
#include "ThreadCollection.h"
int GetRandomInt( bool bInit, int limit )
{ int result; if(limit<1)return 0;
if(bInit)srand( (unsigned)time( NULL ) );
result = ( rand() ) % limit;
return result;
}
DWORD GetPriorityValue( int nCurSel )
{ DWORD dw = THREAD_PRIORITY_NORMAL;
switch (nCurSel)
{
case 1: dw = (DWORD) THREAD_PRIORITY_IDLE; break;
case 2: dw = (DWORD) THREAD_PRIORITY_LOWEST; break;
case 3: dw = (DWORD) THREAD_PRIORITY_BELOW_NORMAL; break;
case 4:
default:dw = (DWORD) THREAD_PRIORITY_NORMAL; break;
case 5: dw = (DWORD) THREAD_PRIORITY_ABOVE_NORMAL; break;
case 6: dw = (DWORD) THREAD_PRIORITY_HIGHEST; break;
case 7: dw = (DWORD) THREAD_PRIORITY_TIME_CRITICAL; break;
}
return dw;
}
//统计仍在继续活动执行的线程数,
//如果采用自动结束方式,而无需变量:m_hEventKill和m_hEventDead
//此函数也可判别所有线程是否全死
int CThreadCollection::FinishPersonThreads()
{ PERSON_INFO * person; DWORD dwStatus; int i; int nCount = 0;
for(i=personArr.GetUpperBound();i>=0; i--){
person = personArr[i];
if( person && person->pthread ){
//如果现成正常结束执行体或被杀,退出码由dwStatus返回
VERIFY(::GetExitCodeThread(person->pthread->m_hThread, &dwStatus));
if (dwStatus == STILL_ACTIVE) //仍在活动 STATUS_PENDING
{ nCount++; person->pthread->m_bDone = TRUE;
}else{ delete person->pthread; //或者person->pthread->KillThread();
person->pthread = NULL; }
}
Sleep(100);
}
return nCount; //仍在活动的线程数
}
void CThreadCollection::FastKillPersonThreads()
{ PERSON_INFO * person; int i;
// 批量执行杀除:tell all threads to shutdown
for(i=personArr.GetUpperBound();i>=0; i--){
person = personArr[i];
if( person && person->pthread ){
VERIFY( SetEvent(person->pthread->m_hEventKill) );
person->pthread->m_bDone=1; }
}
// wait for all threads to finish shutdown
for (int nThreadsLeft = personArr.GetSize(); nThreadsLeft != 0; )
{
//等待任何一个线程结束死亡(退出执行体EndThread)
WaitForSingleObject(PersonThread::m_hAnotherDead, INFINITE);
Sleep(nThreadsLeft*2); //线程越多等待越长一点 200ms for every 100 threads
nThreadsLeft = 0;
for(i=personArr.GetUpperBound();i>=0; i--){
person = personArr[i];
if( person && person->pthread ){ //逐个等待线程死亡消息,如超时,则计数
if (WaitForSingleObject(person->pthread->m_hEventDead, 0) == WAIT_TIMEOUT)
++nThreadsLeft; //超时没杀死: STILL_ACTIVE 的数量
}
}
//如果已经没有线程超时,则表示所有线程均已死亡
}
// 等待线程可析构,并析构对象:delete all thread objects
for(i=personArr.GetUpperBound();i>=0; i--){
person = personArr[i];
if( person && person->pthread ){
VERIFY(WaitForSingleObject(person->pthread->m_hThread, INFINITE) == WAIT_OBJECT_0);
delete person->pthread; person->pthread=NULL;
personArr.RemoveAt(i);
}
}
}
// 利用单个线程的杀除,循环清除集合中所有线程,没有考虑并发清除,速度较慢
// KillThreadsSlow is much easier to understand since the process of
// killing a thread is encapsulated in KillThread. If you get more
// than 50 threads running, however, you'll notice quite a difference
// between this method and the one above.
void CThreadCollection::SlowKillPersonThreads()
{ // Iterate through the threads killing each
// KillThread doesn't return until the Thread is dead
for(int i=personArr.GetUpperBound();i>=0; i--){
PERSON_INFO *person = personArr[i];
if( person && person->pthread ){
person->pthread->KillThread();
person->pthread=NULL; personArr.RemoveAt(i);
}
}
}
// 请利用定义FAST_KILL_THREADS,比较两者深度差异
#define FAST_KILL_THREADS
void CThreadCollection::DestroyThreadCollection()
{ if(!bThreadsPause)ToggleCollectionThreadsPause(true);
ToggleCollectionThreadsPause(false); // 让所有线程处于执行中(resume)
//如果是自动结束方式可采用FinishPersonThreads
#ifdef FAST_KILL_THREADS
FastKillPersonThreads();
#else
SlowKillPersonThreads();
#endif
personArr.RemoveAll(); dinnerToolArr.RemoveAll();
threadsResumeArr.RemoveAll();
competeMap.RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////////
#include "ChildView.h"
CThreadCollection::CThreadCollection()
{ fSyncChecked=false; fBlockChecked=false; bUnBlockSelf=false;
bThreadsPause=true; bUpdateNotify=false;
// Initialize static members of PersonThread
InitializeCriticalSection(&PersonThread::m_criLock);
}
CThreadCollection::~CThreadCollection()
{ DestroyThreadCollection();
DeleteCriticalSection(&PersonThread::m_criLock);
}
void CThreadCollection::SetDisplayCoordinate(CPoint *pt, int ra, int de)
{ point = *pt; rr =ra; delta =de; }
void CThreadCollection::UpdateNotify( PERSON_INFO * person )
{ if(!bUpdateNotify) return;
if(m_pWnd!= NULL){
CDC*pDC = ((CChildView*)m_pWnd)->GetWindowDC(); //如果不用CChildView类型则坐标无剪
DrawCollectionResult(pDC); }
if (m_pListBox != NULL)
{ int x = m_pListBox->AddString(person->message);
m_pListBox->SetCurSel(x);
if (m_pListBox->GetCount() > 400) m_pListBox->DeleteString(0); //保留最近的100条记录
}
}
void CThreadCollection::DrawCollectionResult(CDC *pDC)
{
PERSON_INFO * person;
int x,y,r,xx,yy,dd, size; char chrs[3]; double abc;
size = min(personArr.GetSize(),dinnerToolArr.GetSize());
x=point.x; y=point.y ; r=rr; dd = delta;
//清除显示区
//m_dc.Draw3dRect(x,y,cx,cy,RGB(250,250,250),RGB(200,200,200));
pDC->Ellipse(x-r,y-r,x+r,y+r); //显示餐桌
for(int i=0; i<size; i++){
abc= i*PI2/size;
person = personArr[i]; chrs[2]=0;
//显示序号
CString str; str.Format("%02d",i);
xx = (int)(x+(r+2*dd)*cos(abc));
yy = (int)(y+(r+2*dd)*sin(abc));
CRect rc1(xx-10,yy-10, xx+10,yy+10);
pDC->DrawText(str, &rc1,0);
//显示手中的餐具
xx = (int)(x+(r+dd)*cos(abc));
yy = (int)(y+(r+dd)*sin(abc));
CRect rc(xx-10,yy-10, xx+10,yy+10);
if(person->status==FINISHDOWN)
strcpy(chrs,"完");
else{
chrs[0] = (person->tools&1) ? 'k':'_';
chrs[1] = (person->tools&2) ? 'f':'_';
}
if(person->status==BLOCK) pDC->SetTextColor(RGB(255,0,0));
else if(person->status==CATCHING)pDC->SetTextColor(RGB(0,0,255));
else pDC->SetTextColor(RGB(0,0,0));
pDC->DrawText(chrs, &rc,0); //dc.SetPixel(xx,yy, RGB(255,0,0));
//显示桌上所剩餐具
abc = i*PI2/size + PI/size;
xx = (int)(x+(r-2*dd)*cos(abc));
yy = (int)(y+(r-2*dd)*sin(abc));
CRect rc0(xx-10,yy-10, xx+10,yy+10);
chrs[0] = (dinnerToolArr[i]&1) ? 'k':'_';
chrs[1] = (dinnerToolArr[i]&2) ? 'f':'_';
pDC->SetTextColor(RGB(0,0,0));
pDC->DrawText(chrs, &rc0,0);
}
}
//////////////////////////////////////////////////////////////////////////////
int CThreadCollection::GetItemsUpper()
{ return min(personArr.GetUpperBound(),dinnerToolArr.GetUpperBound()); }
void CThreadCollection::CreateRandomMap(CUIntArray &Arr, int nums)
{ int i, size, val;
Arr.RemoveAll();
while(1){
val = rand()%nums; //GetRandomInt( nums );
size = Arr.GetSize(); if(size==nums)break;
for(i=0; i<size; i++){ if(Arr[i]==(unsigned int)val)break; }
if(i==size || size<1){ Arr.Add(val); }
}
}
void CThreadCollection::SetupThreadStepTime( int delay )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -