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