#pragma once /////////////////////////////////////////////////////////////////////// // QueuedWorkItems.h - child thread processes enqueued work items // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2016 // /////////////////////////////////////////////////////////////////////// /* * A single child thread processes work items equeued by main thread */ #include #include #include "../Cpp11-BlockingQueue/Cpp11-BlockingQueue.h" template using WorkItem = std::function; /////////////////////////////////////////////////////////////////////// // class to process work items // - each work item is processed sequentially on a single child thread template class ProcessWorkItem { public: void start(); void doWork(WorkItem* pWi); Result result(); void wait(); ~ProcessWorkItem(); private: std::thread* _pThread; BlockingQueue*> _workItemQueue; BlockingQueue _resultsQueue; }; //----< wait for child thread to terminate >--------------------------- template void ProcessWorkItem::wait() { _pThread->join(); } //----< enqueue work item >-------------------------------------------- template void ProcessWorkItem::doWork(WorkItem* pWi) { _workItemQueue.enQ(pWi); } //----< retrieve results with blocking call >-------------------------- template Result ProcessWorkItem::result() { return _resultsQueue.deQ(); } //----< start child thread that dequeus work items >------------------- template void ProcessWorkItem::start() { std::function threadProc = [&]() { while (true) { WorkItem* pWi = _workItemQueue.deQ(); if (pWi == nullptr) { std::cout << "\n shutting down work item processing"; return; } Result result = (*pWi)(); _resultsQueue.enQ(result); } }; _pThread = new std::thread(threadProc); } //----< clean up heap >------------------------------------------------ template ProcessWorkItem::~ProcessWorkItem() { delete _pThread; }