I know that this is a very old thread. However, this was a great help. I just wish it was more easy to follow. I'm a beginner from the Windows side of the world. So put up this simple guide for those who are beginners like me. For Visual Studio users, here's a more complete example (But not the safest I think). Make sure you add the Boost Lib, and the Includes Folder.
Using Visual Studio 2010:
There is a part of the code from the main.cpp that you can uncomment which will allow the program to stop the worker thread before it completes its task. It then stops gracefully.
ThreadedFib.h - The Class Header file
#pragma once #include <boost/bind.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/shared_ptr.hpp> #include <vector> #include "boost/date_time/posix_time/posix_time.hpp" class CThreadedFib { public: // constructor CThreadedFib(void); // destructor ~CThreadedFib(void); // Create the thread and start work void Go(); // Stops the thread void stop(); // returns that value of the vector at the nth element - element unsigned long get_FibonacciAt(int element); // returns the current vector size int get_VectorSize(); // returns if the current worker is busy bool get_isBusy(); // sets the maximum value to check void set_FibSteps(int fibSteps); boost::posix_time::time_duration CThreadedFib::get_Duration(); private: boost::posix_time::ptime m_TimeStart; boost::posix_time::ptime m_TimeStop; // is the worker busy? stores this variable. bool m_Busy; // private field for the maximum value to check int m_FibSteps; // true if a stop was requested, false otherwise volatile bool m_stoprequested; // thread pointer boost::shared_ptr<boost::thread> m_thread; // mutex - locks following variables to current thread boost::mutex m_mutex; // the vector which stores the fib sequence std::vector<unsigned long> m_fibonacci_values; // the basic fibonacci function - using unsigned long for max efficiency unsigned long fibonacci_number(unsigned long num); // Compute and save fibonacci numbers as fast as possible void do_work(); };
ThreadedFib.cpp - The Class Header file
#include "ThreadedFib.h" #include <boost/bind.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/shared_ptr.hpp> #include <vector> // constructor implementation CThreadedFib::CThreadedFib(void) { this->m_Busy = false; this->m_FibSteps = 95; this->m_stoprequested = false; } // destructor implementation CThreadedFib::~CThreadedFib(void) { boost::mutex::scoped_lock l(this->m_mutex); if (this->m_Busy == true) { this->stop(); } } bool CThreadedFib::get_isBusy() { return this->m_Busy; } // starts the worker thread. void CThreadedFib::Go() { if (!this->m_Busy) { this->m_TimeStart = boost::posix_time::second_clock::local_time(); this->m_Busy = true; this->m_stoprequested = false; assert(!this->m_thread); this->m_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CThreadedFib::do_work, this))); } } // returns the current size of the vector int CThreadedFib::get_VectorSize() { boost::mutex::scoped_lock l(this->m_mutex); return this->m_fibonacci_values.size(); } // stops the thread worker if it's running void CThreadedFib::stop() // Note 1 { if (this->m_Busy == true) { assert(this->m_thread); this->m_stoprequested = true; this->m_thread->join(); this->m_Busy = false; } } // returns the current value of the unsigned long CThreadedFib::get_FibonacciAt(int element) { boost::mutex::scoped_lock l(this->m_mutex); //Note 2 return this->m_fibonacci_values.at(element); } unsigned long CThreadedFib::fibonacci_number(unsigned long num) { switch(num) { case 0: return 0; case 1: return 1; default: return this->fibonacci_number(num-2) + this->fibonacci_number(num - 1); }; } // Compute and save fibonacci numbers as fast as possible void CThreadedFib::do_work() { int iteration = 0; while (!this->m_stoprequested && iteration < this->m_FibSteps) { int value = this->fibonacci_number(++iteration); boost::mutex::scoped_lock l(this->m_mutex); this->m_fibonacci_values.push_back(value); } boost::mutex::scoped_lock l(this->m_mutex); this->m_Busy = false; this->m_stoprequested = false; this->m_TimeStop = boost::posix_time::second_clock::local_time(); } void CThreadedFib::set_FibSteps(int fibSteps) { boost::mutex::scoped_lock l(this->m_mutex); this->m_FibSteps = fibSteps; } boost::posix_time::time_duration CThreadedFib::get_Duration() { return this->m_TimeStop - this->m_TimeStart; }
main.cpp - The Class Header file
#include <iostream> #include <stdio.h> #include <boost/algorithm/string.hpp> #include <Windows.h> #include "ThreadedFib.h" #include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::posix_time; using namespace std; using namespace boost; string printTime() { ptime now = second_clock::local_time(); return to_simple_string(now); } int main() { // maximum fibonacci number to get int max = 60; // the current size of the vector element holds the fib sequence int size; // the value of the nth element of the vector unsigned long i; // creates the fib worker cout << printTime() << ": Creating the fib worker." << std::endl; CThreadedFib fib; // initiallizes the new max value (default to 10 - check constructor) fib.set_FibSteps(max); // Starts the fib worker cout << printTime() << ": Starting the fib worker." << std::endl; fib.Go(); // to give the worker a jump start. cout << printTime() << ": Sleeping for 2 seconds." << std::endl; Sleep(2000); // Loops and checks if we have reached the max value to get the fib num. while (fib.get_VectorSize() <= max && fib.get_isBusy()) { // make sure that the vector size > 0, else there'd be no content if (fib.get_VectorSize() > 0) { // This part you can turn on if you want to stop before // the completion of the entire loop to the fib of max. //if (fib.get_VectorSize() > 35) { // fib.stop(); //} // get the size of the vector size = fib.get_VectorSize(); // set i as the last value calculated i = fib.get_FibonacciAt(size-1); // show resluts cout << printTime() << ": The value of fib @ " << size << " is " << i << std::endl; // sleep again. cout << printTime() << ": Sleeping for another 2 seconds." << std::endl; Sleep(2000); } } cout << printTime() << ": Stopping fib worker." << std::endl; fib.stop(); cout << printTime() << ": Sleeping for 2 seconds to stop." << std::endl; Sleep(2000); cout << printTime() << ": Geting the number of iterations." << std::endl; size = fib.get_VectorSize(); i = fib.get_FibonacciAt(size-1); cout << printTime() << ": The value of fib(" << size << ") is " << i << std::endl; cout << printTime() << ": Real solving time duration was " << to_simple_string(fib.get_Duration()) << std::endl; cout << "Press any key to continue!" << std::endl; getchar(); return 0; }
Recent comments
10 sec ago
2 hours 55 min ago
2 hours 55 min ago
13 hours 9 min ago
14 hours 37 min ago
14 hours 37 min ago
14 hours 37 min ago
21 hours 54 min ago
2 weeks 3 days ago
4 weeks 4 days ago