⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threadcollection.cpp

📁 模拟哲学家就餐过程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -