1// excerpts from http://code.google.com/p/muduo/ 2// 3// Use of this source code is governed by a BSD-style license 4// that can be found in the License file. 5// 6// Author: Shuo Chen (giantchen at gmail dot com) 7 8#include "ThreadPool.h" 9#include "Exception.h" 10 11#include <boost/bind.hpp> 12#include <assert.h> 13#include <stdio.h> 14 15using namespace muduo; 16 17ThreadPool::ThreadPool(const std::string& name) 18 : mutex_(), 19 cond_(mutex_), 20 name_(name), 21 running_(false) 22{ 23} 24 25ThreadPool::~ThreadPool() 26{ 27 if (running_) 28 { 29 stop(); 30 } 31} 32 33void ThreadPool::start(int numThreads) 34{ 35 assert(threads_.empty()); 36 running_ = true; 37 threads_.reserve(numThreads); 38 for (int i = 0; i < numThreads; ++i) 39 { 40 char id[32]; 41 snprintf(id, sizeof id, "%d", i); 42 threads_.push_back(new muduo::Thread( 43 boost::bind(&ThreadPool::runInThread, this), name_+id)); 44 threads_[i].start(); 45 } 46} 47 48void ThreadPool::stop() 49{ 50 running_ = false; 51 cond_.notifyAll(); 52 for_each(threads_.begin(), 53 threads_.end(), 54 boost::bind(&muduo::Thread::join, _1)); 55} 56 57void ThreadPool::run(const Task& task) 58{ 59 if (threads_.empty()) 60 { 61 task(); 62 } 63 else 64 { 65 MutexLockGuard lock(mutex_); 66 queue_.push_back(task); 67 cond_.notify(); 68 } 69} 70 71ThreadPool::Task ThreadPool::take() 72{ 73 MutexLockGuard lock(mutex_); 74 while (queue_.empty() && running_) 75 { 76 cond_.wait(); 77 } 78 Task task; 79 if(!queue_.empty()) 80 { 81 task = queue_.front(); 82 queue_.pop_front(); 83 } 84 return task; 85} 86 87void ThreadPool::runInThread() 88{ 89 try 90 { 91 while (running_) 92 { 93 Task task(take()); 94 if (task) 95 { 96 task(); 97 } 98 } 99 } 100 catch (const Exception& ex) 101 { 102 fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 103 fprintf(stderr, "reason: %s\n", ex.what()); 104 fprintf(stderr, "stack trace: %s\n", ex.stackTrace()); 105 abort(); 106 } 107 catch (const std::exception& ex) 108 { 109 fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 110 fprintf(stderr, "reason: %s\n", ex.what()); 111 abort(); 112 } 113 catch (...) 114 { 115 fprintf(stderr, "unknown exception caught in ThreadPool %s\n", name_.c_str()); 116 abort(); 117 } 118} 119 120