您的位置:首页 > 其它

zthread学习 实例八 任务终止(一)——观赏植物园

2011-05-27 12:22 429 查看
前面的几个例子中,使用了“退出标志”或Cancelable接口以适当的方式来终止一个任务,但某些情况下任务必须突然结束掉,这样终止任务将会所产生一些问题。

举例:模拟计数,公园委员会想要了解每天有多少从通过公园的 多个 入口进入了。

首先是一个互斥输出类,避免多个线程输出出现的混乱

#ifndef DISPLAY_H
#define DISPLAY_H
#include "zthread/Cancelable.h"
#include "zthread/ZThread.h"
#include <iostream>
#include <sstream>
using namespace ZThread;
using namespace std;
class Display
{
public:
void OutPut(ostringstream& os)
{
Guard<Mutex> g(Lock);
cout<<os.str();
}
private:
Mutex Lock;
};
#endif


模拟程序如下:

#include <vld.h>
#include "stdafx.h"
#include "zthread/Thread.h"
#include "zthread/FastMutex.h"
#include "zthread/CountedPtr.h"
#include <iostream>
#include <vector>
#include <ctime>
#include "Display.h"
using namespace ZThread;
using namespace std;
//总计数器
class Count : public Cancelable
{
public:
Count(): nCount(0), bPaused(false),bCanceld(false){}

int increment()
{
Guard<FastMutex> g(Lock);	//*************
int temp = nCount;
if (rand() % 2 == 0)		//放大出错的可能
{
Thread::yield();
}
return (nCount = ++temp);
}
int value()
{
Guard<FastMutex> g(Lock);
return nCount;
}

void cancel()
{
Guard<FastMutex> g(Lock);
bCanceld = true;
}
bool isCanceled()
{
Guard<FastMutex> g(Lock);
return bCanceld;
}

void pause()
{
Guard<FastMutex> g(Lock);
bPaused = true;
}
bool isPaused()
{
Guard<FastMutex> g(Lock);
return bPaused;
}

private:
FastMutex	Lock;
int			nCount;
bool		bPaused, bCanceld;
};
//门口计数
class Entrance : public Runnable
{
public:
Entrance(CountedPtr<Count>& ApCount, CountedPtr<Display>& ApDisplay, int idn = 0)
:pCount(ApCount), pDisplay(ApDisplay), id(idn), bWaittingforCancel(false), Number(0) {}
void run()
{
try
{
while (!pCount->isPaused())		//控制总计数器
{
Number++;					//自身计数器
{
ostringstream os;
//输出总数
os << *this << " Total: " << pCount->increment() <<endl;
pDisplay->OutPut(os);
}
Thread::sleep(100);
}
bWaittingforCancel = true;		//GetValue()时的阴塞消息
while (!pCount->isCanceled())
Thread::sleep(100);
ostringstream os;
os << " Terminating: " << *this <<endl;
pDisplay->OutPut(os);
}
catch (Synchronization_Exception* e)
{
cerr << " Exception: "<< e->what() <<endl;
}
}

int GetValue()
{
while (pCount->isPaused() && !bWaittingforCancel)	//确保当前计数器和总计数器都已经退出
Thread::sleep(100);

return Number;
}

friend ostream& operator<< (ostream& os, const Entrance& e)
{
return os << " Entrance "<< e.id << " : " <<e.Number;
}

private:
CountedPtr<Count>	pCount;		//共享的总计数器
CountedPtr<Display>	pDisplay;

int Number;
int id;

bool bWaittingforCancel;
};
int _tmain(int argc, _TCHAR* argv[])
{
srand(time(0));

CountedPtr<Count> pCount(new Count);
vector<Entrance*> v;

CountedPtr<Display> pDisplay(new Display);

try
{
ThreadedExecutor excutor;

for (int i = 0; i < 5; i++)
{
Entrance* pTask = new Entrance(pCount,pDisplay, i);
excutor.execute(pTask);
v.push_back(pTask);
}

cin.get();
pCount->pause();

int nSum = 0;

vector<Entrance*>:: iterator it = v.begin();

while (it != v.end())		//校对各个门口计数器的和是否和总计数器的结果相同,以此来检验互斥是否是成功
{
nSum += (*it)->GetValue();
it++;
}

ostringstream os;
os << "Total : " << pCount->value() << endl << "Sum of Entrance : " << nSum << endl;

pDisplay->OutPut(os);

pCount->cancel();

cin.get();
}
catch (Synchronization_Exception* e)
{
cerr << " Exception: "<< e->what() <<endl;
}

return 0;
}


输出结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: