📄 threadcollection.cpp
字号:
{ 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 + -