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

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

输出结果:

zthread学习 实例八 任务终止(一)——观赏植物园_第1张图片

你可能感兴趣的:(thread,exception,OS,iterator,Class,任务)