ThreadPool.cc 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "Thread/ThreadPool.h"
  2. namespace Egametang {
  3. ThreadPool::ThreadPool(int num) :
  4. threadNum(num), running(true), workNum(0)
  5. {
  6. if (num == 0)
  7. {
  8. threadNum = boost::thread::hardware_concurrency();
  9. }
  10. for (int i = 0; i < threadNum; ++i)
  11. {
  12. ThreadPtr t(new boost::thread(
  13. boost::bind(&ThreadPool::Runner, this)));
  14. threads.push_back(t);
  15. t->detach();
  16. ++workNum;
  17. }
  18. }
  19. ThreadPool::~ThreadPool()
  20. {
  21. boost::mutex::scoped_lock lock(mutex);
  22. running = false;
  23. cond.notify_all();
  24. while (workNum > 0)
  25. {
  26. done.wait(lock);
  27. }
  28. }
  29. void ThreadPool::Wait()
  30. {
  31. boost::mutex::scoped_lock lock(mutex);
  32. running = false;
  33. cond.notify_all();
  34. while (workNum > 0)
  35. {
  36. done.wait(lock);
  37. }
  38. }
  39. void ThreadPool::Runner()
  40. {
  41. bool continued = true;
  42. while (continued)
  43. {
  44. boost::function<void (void)> task;
  45. {
  46. boost::mutex::scoped_lock lock(mutex);
  47. while (running && tasks.empty())
  48. {
  49. cond.wait(lock);
  50. }
  51. if (!tasks.empty())
  52. {
  53. task = tasks.front();
  54. tasks.pop_front();
  55. }
  56. continued = running || !tasks.empty();
  57. }
  58. if (task)
  59. {
  60. task();
  61. }
  62. }
  63. if (--workNum == 0)
  64. {
  65. done.notify_one();
  66. }
  67. }
  68. bool ThreadPool::Schedule(boost::function<void (void)> task)
  69. {
  70. {
  71. boost::mutex::scoped_lock lock(mutex);
  72. if (!running)
  73. {
  74. return false;
  75. }
  76. tasks.push_back(task);
  77. }
  78. cond.notify_one();
  79. return true;
  80. }
  81. } // namespace Egametang