C++ 併發編程(四):基於 Asio 的線程池

目前項目中使用的線程池(詳見:http://threadpool.sourceforge...),雖然能用,可是代碼複雜且好久沒有人維護了。ios

本文結合 Thread 和 Asio,實現了一個線程池。一二十行代碼,不能更簡單了!異步

頭文件:wordpress

#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>

#define BOOST_ASIO_NO_DEPRECATED
#include "boost/asio.hpp"

線程池類:post

class ThreadPool {
public:
  explicit ThreadPool(std::size_t size)
      : work_guard_(boost::asio::make_work_guard(io_context_)) {
    workers_.reserve(size);
    for (std::size_t i = 0; i < size; ++i) {
      workers_.emplace_back(&boost::asio::io_context::run, &io_context_);
    }
  }

  ~ThreadPool() {
    io_context_.stop();

    for (auto& w : workers_) {
      w.join();
    }
  }

  // Add new work item to the pool.
  template<class F>
  void Enqueue(F f) {
    boost::asio::post(io_context_, f);
  }

private:
  std::vector<std::thread> workers_;
  boost::asio::io_context io_context_;

  typedef boost::asio::io_context::executor_type ExecutorType;
  boost::asio::executor_work_guard<ExecutorType> work_guard_;
};

成員變量 work_guard_ 的做用是,讓 io_context 即便在沒有異步任務可執行時也保持運行(即 io_context::run 不返回)。詳見 StackOverflow 的討論:Why should I use io_service::work?this

示例:.net

// For output.
std::mutex g_io_mutex;

int main() {
  // Create a thread pool of 4 worker threads.
  ThreadPool pool(4);

  // Queue a bunch of work items.
  for (int i = 0; i < 8; ++i) {
    pool.Enqueue([i] {
      {
        std::lock_guard<std::mutex> lock(g_io_mutex);
        std::cout << "Hello" << "(" << i << ") " << std::endl;
      }

      std::this_thread::sleep_for(std::chrono::seconds(1));

      {
        std::lock_guard<std::mutex> lock(g_io_mutex);
        std::cout << "World" << "(" << i << ")" << std::endl;
      }
    });
  }

  return 0;
}

輸出(每次都不同):線程

Hello(0)
Hello(1)
Hello(2)
Hello(3)
<Wait about 1 second>
World(3)
World(2)
World(1)
World(0)

參考:code

相關文章
相關標籤/搜索