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

📄 threadcollection.cpp

📁 模拟哲学家就餐过程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{	PERSON_INFO * person;  int upper=personArr.GetUpperBound();
	for(int i=0; i<=upper; i++){
		person = personArr[i];	if( person )person->steptime = delay;
	}
}

void  CThreadCollection::initThreadCollectionClass(CWnd* pWnd, CListBox*pBox, int nums, int delay)
{	  PERSON_INFO * person;
 
      srand( (unsigned)time( NULL ) ); //初始化随机种子
	  m_pWnd = pWnd;  m_pListBox=pBox; m_step=0; nContinousPrompt=-1; counter=0; 
	  CreateRandomMap( threadsResumeArr, nums );
	  for(int i=0; i<nums; i++){
		person = new PERSON_INFO(); if(!person)break;
		dinnerToolArr.Add(3);			//放置刀叉
		person->tools   = 0;			//无刀无叉
		person->step    = 0;			//第一步
		person->index   = i;			//位置序号
		person->status  = CATCHING;		//可取餐具
		person->pthread = NULL;
		person->steptime = delay;
	    person->defaultpriority = GetPriorityValue( 1+GetRandomInt(0,7) ) ; //缺省随机优先级
		personArr.Add( (PERSON_INFO*)person );
		person->compete.what=0; 
	  }
	  if(person){
		  bool bCopy = bUpdateNotify;   bUpdateNotify = true; //显示第一行开始信息	
		  person->message.Format("There are %d persons to beginging...", nums);
		  UpdateNotify( person );  bUpdateNotify = bCopy;
	  }
	  ((CChildView*)m_pWnd)->Invalidate();
}

void CThreadCollection::initCollectionThreads(int nCurSel)
{	PERSON_INFO * person;  int upper=personArr.GetUpperBound();

	for(int i=0; i<=upper; i++){ person = personArr[i];
		if( person && person->pthread==NULL ){
			DWORD dw = (nCurSel==0) ? person->defaultpriority : GetPriorityValue( nCurSel );
			person->pthread = CreateBeginThread(person, dw);  }
	}
	if(!bThreadsPause)ToggleCollectionThreadsPause(false); //没有挂起则激活所有线程
}

PersonThread* CThreadCollection::CreateBeginThread( PERSON_INFO * person, DWORD nPriority )
{	PersonThread *pThread = new PersonThread();
	ASSERT_VALID(pThread); 	if (pThread == NULL)return NULL;

	pThread->m_pThreadParams = NULL;  
	pThread->initPersonThread(this, person); 
	// Create Thread in a suspended state so we can set the Priority before it starts getting away from us
	if (!pThread->CreateThread(CREATE_SUSPENDED)){	delete pThread;	return NULL;	}

	VERIFY( pThread->SetThreadPriority(nPriority) );
	return  pThread;

	//或者可以如下创建
	//pThread = AfxBeginThread(RUNTIME_CLASS(PersonThread), THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);
	//if(pThread)pthread->initPersonThread(this, person);  pThread->m_pThreadParams = NULL; return pThread;
}

// 注意随机顺序与自然顺序的不同效果
#define RANDOM_RESUME_THREADS

void CThreadCollection::ToggleCollectionThreadsPause(bool bPaused)
{	PERSON_INFO * person; int i,r,upper;
	bThreadsPause = bPaused;

#ifdef  RANDOM_RESUME_THREADS
	upper = threadsResumeArr.GetUpperBound();
	for(r=0; r<=upper; r++){
		i = threadsResumeArr[r]; if(i>upper)continue;  
		person = personArr[i];
		if( person && person->pthread ) {
			if (bPaused)person->pthread->SuspendThread();
			else person->pthread->ResumeThread();
		}
	}

#else

	upper = personArr.GetUpperBound();
	for(i=0; i<=upper; i++){
		person = personArr[i];
		if( person && person->pthread ) {
			if (bPaused)person->pthread->SuspendThread();
			else person->pthread->ResumeThread();
		}
	}
#endif
}

DWORD CThreadCollection::SetPersonThreadsPriority( int nCurSel )
{	PERSON_INFO * person;  	DWORD dw;

	for(int i=0; i<=personArr.GetUpperBound();i++){
		person = personArr[i];
		dw     = (nCurSel==0) ? person->defaultpriority : GetPriorityValue( nCurSel );
		if( person && person->pthread ) person->pthread->SetThreadPriority(dw);
	}
	return dw;
}

void CThreadCollection::SetCurrentPriorityClass(int nCurSel)
{	DWORD dw = NORMAL_PRIORITY_CLASS;
	switch (nCurSel)
	{
	case 0:	dw = IDLE_PRIORITY_CLASS;	break;
	case 1:
	default:dw = NORMAL_PRIORITY_CLASS;	break;
	case 2:	dw = HIGH_PRIORITY_CLASS;	break;
	case 3:	dw = REALTIME_PRIORITY_CLASS;break;
	}
	SetPriorityClass(GetCurrentProcess(), dw);
}

/////////////////////////////////////////////////////////////////////////////

int   CThreadCollection::CheckPersonCatchStatus(int status)
{	PERSON_INFO * person;

	for(int i=0; i<=personArr.GetUpperBound(); i++){
		person = personArr[i];
		if( person && person->pthread ){
			if(person->status==status)return 1;
		}
	}
	return 0; //已经没有正在抓取
}

int   CThreadCollection::CheckPersonFinishStatus()
{	PERSON_INFO * person;

	for(int i=0; i<=personArr.GetUpperBound(); i++){
		person = personArr[i];
		if( person && person->pthread ){
			if(person->status!=FINISHDOWN)return 0;	}
	}
	return 1; //已经全部完成
}

void  CThreadCollection::PutdownDinnerToolkit(PERSON_INFO * person, int set, int mask)
{     int index = person->index;
	  int loc   = (set==KNIFE_BIT) ? person->knife : person->fork;
	  dinnerToolArr[loc]      |= set;   //放回原地, 一个比特
	  personArr[index]->tools &= mask;   //清除拿到标志, 也可不清, 因线程已结束
	
      person->message.Format("Person %d put back a %s to the location %d", index, 
		   (set==FORK_BIT)?"fork":"knife", loc);
	  UpdateNotify( person );
}		

//在临界区内
int   CThreadCollection::CatchDinnerToolkit(PERSON_INFO * person, bool fromLeft, bool isFork)
{	  counter++; bool NeighborsBlocked, SelfBlocked ;  
	  int upper = GetItemsUpper();     int idx = person->index; 	
	  int loc   = (fromLeft) ? idx: ( (idx==0)?  upper: idx-1 ) ;
	  int set  = (isFork) ? FORK_BIT  : KNIFE_BIT ; 
	  int mask = (isFork) ? FORK_MASK : KNIFE_MASK;

	  if( !(person->tools & set) && (dinnerToolArr[loc] & set) ){
		  dinnerToolArr[loc]	&= mask;		//取走刀或叉, 一个比特

		  //当自己如果不取它,则永久没有机会能拿全时,是否自己优先还是邻居优先?
		  SelfBlocked      = (person->pthread->CheckOneToolkit(idx, set, upper)==BLOCK) ? true : false ;
		  NeighborsBlocked = WillBlockNeighbor(idx, set, upper);	
		  if(SelfBlocked && NeighborsBlocked){ person->compete.loc=loc;person->compete.what=set; }

		  if( !(bUnBlockSelf&&SelfBlocked) && NeighborsBlocked && fBlockChecked){
			  dinnerToolArr[loc] |= set;			//不取, 邻居优先
		  }else{
			  person->tools			|= set;			//拿得刀或叉的标志
			  if(set==FORK_BIT) person->fork= loc;	//拿得叉的位置
			  else  person->knife	 = loc;			//拿得刀的位置
			  
			  person->message.Format("Person %d catchs a %s from the %s location %d at step %d", person->index, 
				 (set==FORK_BIT)?"fork":"knife", (fromLeft)?"left":"right",  loc, person->step+1);
			  UpdateNotify( person );  
			  return 1;
		  }
	  }
	  return 0;
}		 

int   CThreadCollection::WillBlockNeighbor(int iCurrent, int kf, int upper)
{	  int neighbor, neighborstatus;
	  for(int left=1; left>=0; left--){  //左右两人	
		   if(left==1)neighbor = (iCurrent==upper) ? 0: (iCurrent+1);
		     else     neighbor = (iCurrent==0) ? upper: (iCurrent-1);

		   if(personArr[neighbor] && personArr[neighbor]->pthread){
		      neighborstatus = personArr[neighbor]->pthread->CheckOneToolkit(neighbor, kf, upper);
		      if( neighborstatus==BLOCK ) return 1;  
		   }
	  }
	  return 0;
}

void   CThreadCollection::PromptContinousCheckBox(int show) //SW_SHOW
{     nContinousPrompt = show ; 
	  if(show==SW_SHOW)m_pWnd->GetDlgItem(IDC_CONTINOUSBTN)->ShowWindow(SW_SHOW);  
}

void   CThreadCollection::StatCompetePersons()
{       PERSON_INFO * person;
		for(int i=0; i<=personArr.GetUpperBound(); i++){
			person = personArr[i];
			if( person && person->compete.what!=0){
				person->message.Format("The person %d compete the %s at location %d %s", person->index,
					(person->compete.what==FORK_BIT)?"fork":"knife", person->compete.loc, (person->status==BLOCK)?": BLOCKED":"GET");
				UpdateNotify( person ); person->compete.what=0;
			}else if(person->status==BLOCK){
				person->message.Format("The person %d can not catch the %s anywhere", 
					person->index, (person->tools&FORK_BIT)?"fork":"knife");
				UpdateNotify( person );
			}
		}
		if(!person)person=person = personArr[0];
		person->message.Format("下面开始第 %d 轮就餐,第 %d 轮竞争", m_step+1, m_step+2);
		UpdateNotify( person );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -