{"id":345,"date":"2023-09-11T23:42:36","date_gmt":"2023-09-11T15:42:36","guid":{"rendered":"https:\/\/blog.kishere.cn\/?p=345"},"modified":"2024-07-12T09:48:03","modified_gmt":"2024-07-12T01:48:03","slug":"c%e7%ba%bf%e7%a8%8b%e6%b1%a0","status":"publish","type":"post","link":"https:\/\/blog.kishere.cn\/?p=345","title":{"rendered":"C++\u7ebf\u7a0b\u6c60"},"content":{"rendered":"<p>\u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u7ebf\u7a0b\u6c60\uff0c\u7528C++\u6807\u51c6\u5b9e\u73b0<\/p>\n<pre><code class=\"language-cpp line-numbers\">#include &lt;thread&gt;\n#include &lt;vector&gt;\n#include &lt;queue&gt;\n#include &lt;mutex&gt;\n#include &lt;condition_variable&gt;\n#include &lt;future&gt;\n#include &lt;functional&gt;\n#include &lt;stdexcept&gt;\n\nclass ThreadPool {\npublic:\n  ThreadPool(size_t numThreads);\n  ~ThreadPool();\n\n  template&lt;typename F, typename... Args&gt;\n  auto enqueue(F&amp;&amp; f, Args&amp;&amp;... args) -&gt; std::future&lt;decltype(f(args...))&gt;;\n\nprivate:\n  std::vector&lt;std::thread&gt; threads;\n  std::queue&lt;std::function&lt;void()&gt;&gt; tasks;\n\n  std::mutex queueMutex;\n  std::condition_variable condition;\n  bool stop{false};\n};\n\n\/\/ \u7ebf\u7a0b\u8fd0\u884c\u51fd\u6570\nvoid ThreadPool::workerThread() {\n  while (true) {\n    std::function&lt;void()&gt; task;\n\n    {\n      std::unique_lock&lt;std::mutex&gt; lock(queueMutex);\n      condition.wait(lock, [this] { return stop || !tasks.empty(); });\n      if (stop &amp;&amp; tasks.empty())\n        return;\n      task = std::move(tasks.front());\n      tasks.pop();\n    }\n\n    task();\n  }\n}\n\n\/\/ \u63d0\u4ea4\u4efb\u52a1\ntemplate&lt;typename F, typename... Args&gt;\nauto ThreadPool::enqueue(F&amp;&amp; f, Args&amp;&amp;... args) -&gt; std::future&lt;decltype(f(args...))&gt; {\n  \/\/ \u5305\u88c5\u4efb\u52a1\n  auto task = std::make_shared&lt;std::packaged_task&lt;decltype(f(args...))(Args...)&gt;&gt;(\n    std::bind(std::forward&lt;F&gt;(f), std::forward&lt;Args&gt;(args)...)\n  );\n\n  std::future&lt;decltype(f(args...))&gt; future = task-&gt;get_future();\n  {\n    std::unique_lock&lt;std::mutex&gt; lock(queueMutex);\n\n    \/\/ \u6dfb\u52a0\u4efb\u52a1\u5230\u961f\u5217\n    tasks.emplace([task]() { (*task)(); });\n  }\n  condition.notify_one();\n  return future;\n}\n\n\/\/ \u7ebf\u7a0b\u6c60\u6784\u9020\u4e0e\u6790\u6784\nThreadPool::ThreadPool(size_t numThreads) {\n  \/\/ \u542f\u52a8\u6307\u5b9a\u6570\u91cf\u7684\u7ebf\u7a0b\n  for(size_t i = 0; i &lt; numThreads; ++i) {\n    threads.emplace_back(\n      std::thread(&amp;ThreadPool::workerThread, this)\n    ); \n  }\n}\n\nThreadPool::~ThreadPool() {\n  {\n    std::unique_lock&lt;std::mutex&gt; lock(queueMutex);\n    stop = true;\n  }\n  condition.notify_all();\n\n  for(std::thread &amp;thread : threads) {\n    thread.join(); \n  }\n}\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u7ebf\u7a0b\u6c60\uff0c\u7528C++\u6807\u51c6\u5b9e\u73b0 #include &lt;thread&gt; #include &lt;vector&gt; #include &lt;queue&gt; #include &lt;mutex&gt; #include &lt;condition_variable&gt; #include &lt;future&gt; #include &lt;functional&gt; #include &lt;stdexcept&gt; class ThreadPool { public: ThreadPool(size_t numThreads); ~ThreadPool(); template&lt;typename F, typename&#8230; Args&gt; auto enqueue(F&amp;&amp; f, Args&amp;&amp;&#8230; args) -&gt; std::future&lt;decltype(f(args&#8230;))&gt;; private: std::vector&lt;std::thread&gt; threads; std::queue&lt;std::function&lt;void()&gt;&gt; tasks; std::mutex queueMutex; std::condition_variable condition; bool stop{false}; }; \/\/ \u7ebf\u7a0b\u8fd0\u884c\u51fd\u6570 void ThreadPool::workerThread() { while (true) { std::function&lt;void()&gt; task; { std::unique_lock&lt;std::mutex&gt; lock(queueMutex); condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop &amp;&amp; tasks.empty()) return; task = std::move(tasks.front()); tasks.pop(); } task(); } } \/\/ \u63d0\u4ea4\u4efb\u52a1 template&lt;typename F, typename&#8230; Args&gt; auto ThreadPool::enqueue(F&amp;&amp; f, Args&amp;&amp;&#8230; args) -&gt; std::future&lt;decltype(f(args&#8230;))&gt; { \/\/ \u5305\u88c5\u4efb\u52a1 auto task = std::make_shared&lt;std::packaged_task&lt;decltype(f(args&#8230;))(Args&#8230;)&gt;&gt;( std::bind(std::forward&lt;F&gt;(f), std::forward&lt;Args&gt;(args)&#8230;) ); std::future&lt;decltype(f(args&#8230;))&gt; future = task-&gt;get_future(); { std::unique_lock&lt;std::mutex&gt; lock(queueMutex); \/\/ \u6dfb\u52a0\u4efb\u52a1\u5230\u961f\u5217 tasks.emplace([task]() { (*task)(); }); } condition.notify_one(); return future; } \/\/ \u7ebf\u7a0b\u6c60\u6784\u9020\u4e0e\u6790\u6784 ThreadPool::ThreadPool(size_t numThreads) { \/\/ \u542f\u52a8\u6307\u5b9a\u6570\u91cf\u7684\u7ebf\u7a0b for(size_t i = 0; i &lt; numThreads; ++i) { threads.emplace_back( std::thread(&amp;ThreadPool::workerThread, this) ); } } ThreadPool::~ThreadPool() { { std::unique_lock&lt;std::mutex&gt; lock(queueMutex); stop = true; } condition.notify_all(); for(std::thread &amp;thread : threads) { thread.join(); } }<\/p>\n","protected":false},"author":1,"featured_media":196,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[11,5],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/posts\/345"}],"collection":[{"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=345"}],"version-history":[{"count":1,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/posts\/345\/revisions"}],"predecessor-version":[{"id":346,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/posts\/345\/revisions\/346"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=\/wp\/v2\/media\/196"}],"wp:attachment":[{"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kishere.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}