1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// FILE threadpool.cc : Implementation of member functions for class threadpool
//////////////////////////////////////////////////////////////////////////
//
// Copyright 1990-2012 Marcus Mo
//
// This file is part of the eclib package.
//
// eclib is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// eclib is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with eclib; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//
//////////////////////////////////////////////////////////////////////////
/**
* threadpool.cc
*
* Simple, no-frills threadpool for Boost threads.
* Some features have been made available specifically for ECLIB.
*
* These include use of verbosity level in constructor, to be
* used for logging. Tasks must also have an overloaded
* operator() which describes what each thread must perform on
* that object. The return value of the task must be
* void, i.e. nothing is returned.
*/
// Compile this only if Boost is installed
#ifdef ECLIB_MULTITHREAD
// Include header files
#include "eclib/threadpool.h"
/**
* Threadpool()
*
* Default constructor. Must call start() before using threadpool.
*/
threadpool::threadpool()
: maxThreads_( 0 ), threadCount_( 0 ), verbose_( -1 ),
work_( new boost::asio::io_service::work( io_service_ ) )
{}
/**
* threadpool()
*
* Main constructor.
*/
threadpool::threadpool( unsigned int numThreads, int verbose )
: work_( new boost::asio::io_service::work( io_service_ ) ) {
start( numThreads, verbose );
}
/**
* ~Threadpool()
*
* Desctructor. Simply calls close()
*/
threadpool::~threadpool() {
close();
}
/**
* start();
*
* Must be called after constructor, and allows for threadpool
* to be restarted after a call to close().
*/
void threadpool::start( unsigned int numThreads, int verbose ) {
// Store verbosity
verbose_ = verbose;
// Store maximum number of threads system can support
maxThreads_ = boost::thread::hardware_concurrency();
// Store actual number of threads to be used.
// If not specified, we use the system limit.
threadCount_ = ( numThreads > 0 ) ? numThreads : maxThreads_;
// We limit the number of threads to the system limit.
// Note: it is best to not use all available threads
if( threadCount_ > maxThreads_ ) {
// Reset limit
threadCount_ = maxThreads_;
// Notify
if( verbose_ ) std::cout << "Requested more threads than available."
<< std::endl;
}
// Declare the final number of threads to be used
if( verbose_ > 1 ) std::cout << "Threadpool will be using " << threadCount_
<< " threads from a total of "
<< maxThreads_ << " threads." << std::endl;
// Create threads and add to threadpool
for( unsigned int i = 0; i < threadCount_-1; i++ ) {
threads_.create_thread( boost::bind( &boost::asio::io_service::run, &io_service_ ) );
}
}
/**
* close()
*
* Closes io_service_ to prevent further
* jobs added to job queue. Joins all threads in
* threadpool; currently running jobs are completed
* before returning control to calling thread.
*
* This blocking method exists in case we wish
* to close the threadpool before end-of-scope,
* or to detect when all previously posted
* jobs have finished.
*/
void threadpool::close() {
// We destroy the work class on the io_service object
// so that we can exit once all jobs posted have finished
work_.reset();
// run() blocks until all posted jobs have finished
io_service_.run();
// We close the threadpool and join all threads
io_service_.stop();
threads_.join_all();
}
/**
* getThreadCount()
*
* Returns number of threads initiated
* in threadpool.
*/
unsigned int threadpool::getThreadCount() {
return threadCount_;
}
/**
* getMaxThreads()
*
* Returns maximum number of threads available.
* Provides easier access.
*/
unsigned int threadpool::getMaxThreads() {
return maxThreads_;
}
#endif // ECLIB_MULTITHREAD
|