前面的几个例子中,使用了“退出标志”或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;
- }
输出结果: