Guest User

Untitled

a guest
Jul 14th, 2019
3,076
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.71 KB | None | 0 0
  1. #include <condition_variable>
  2. #include <functional>
  3. #include <iostream>
  4. #include <future>
  5. #include <vector>
  6. #include <thread>
  7. #include <queue>
  8.  
  9. class ThreadPool
  10. {
  11. public:
  12.     using Task = std::function<void()>;
  13.  
  14.     explicit ThreadPool(std::size_t numThreads)
  15.     {
  16.         start(numThreads);
  17.     }
  18.  
  19.     ~ThreadPool()
  20.     {
  21.         stop();
  22.     }
  23.  
  24.     template<class T>
  25.     auto enqueue(T task)->std::future<decltype(task())>
  26.     {
  27.         auto wrapper = std::make_shared<std::packaged_task<decltype(task()) ()>>(std::move(task));
  28.  
  29.         {
  30.             std::unique_lock<std::mutex> lock{mEventMutex};
  31.             mTasks.emplace([=] {
  32.                 (*wrapper)();
  33.             });
  34.         }
  35.  
  36.         mEventVar.notify_one();
  37.         return wrapper->get_future();
  38.     }
  39.  
  40. private:
  41.     std::vector<std::thread> mThreads;
  42.  
  43.     std::condition_variable mEventVar;
  44.  
  45.     std::mutex mEventMutex;
  46.     bool mStopping = false;
  47.  
  48.     std::queue<Task> mTasks;
  49.  
  50.     void start(std::size_t numThreads)
  51.     {
  52.         for (auto i = 0u; i < numThreads; ++i)
  53.         {
  54.             mThreads.emplace_back([=] {
  55.                 while (true)
  56.                 {
  57.                     Task task;
  58.  
  59.                     {
  60.                         std::unique_lock<std::mutex> lock{mEventMutex};
  61.  
  62.                         mEventVar.wait(lock, [=] { return mStopping || !mTasks.empty(); });
  63.  
  64.                         if (mStopping && mTasks.empty())
  65.                             break;
  66.  
  67.                         task = std::move(mTasks.front());
  68.                         mTasks.pop();
  69.                     }
  70.  
  71.                     task();
  72.                 }
  73.             });
  74.         }
  75.     }
  76.  
  77.     void stop() noexcept
  78.     {
  79.         {
  80.             std::unique_lock<std::mutex> lock{mEventMutex};
  81.             mStopping = true;
  82.         }
  83.  
  84.         mEventVar.notify_all();
  85.  
  86.         for (auto &thread : mThreads)
  87.             thread.join();
  88.     }
  89. };
  90.  
  91. int main()
  92. {
  93.     {
  94.         ThreadPool pool{36};
  95.  
  96.         for (auto i = 0; i < 36; ++i)
  97.         {
  98.             pool.enqueue([] {
  99.                 auto f = 1000000000;
  100.                 while (f > 1)
  101.                     f /= 1.00000001;
  102.             });
  103.         }
  104.     }
  105.  
  106.     return 0;
  107. }
Add Comment
Please, Sign In to add comment