Using boost to implement thread pool | boost thread pool example

Time:2019-11-14

This article starts from my blog https://kezunlin.me/post/f241bd30/, welcome to read!

boost thread pool example

Guide

boost thread pool example with cpp code

code example

#include <iostream>    //std::cout std::endl
#include <thread>      //std::thread
#include <future>      //std::future std::promise
#include <utility>     //std::ref
#include <chrono>      //std::chrono::seconds

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

class ThreadPool {
public:
    explicit ThreadPool(size_t size) : work_(io_service_) {
        for (size_t i = 0; i < size; ++i) {
            workers_.create_thread(
                boost::bind(&boost::asio::io_service::run, &io_service_));
        }
    }

    ~ThreadPool() {
        std::cout << "~ThreadPool" << std::endl;
        io_service_.stop(); // stop before join_all
        workers_.join_all();
    }

    // Add new work item to the pool.
    template<class F>
    void Enqueue(F f) {
        io_service_.post(f);
        //sync, return immediately
    }

private:
    boost::thread_group workers_;
    boost::asio::io_service io_service_;
    boost::asio::io_service::work work_;
};

boost::mutex io_mutex;

void count(int id)
{
    for (int i = 0; i < 10; i++)
    {
        boost::mutex::scoped_lock lock(io_mutex);
        std::cout << id << ":" << i << std::endl;
    }
}

void test_thread()
{
    boost::thread thrd1(boost::bind(&count, 1));
    boost::thread thrd2(boost::bind(&count, 2));
    thrd1.join();
    thrd2.join();
}

void print(int i)
{
    boost::mutex::scoped_lock lock(io_mutex);
    std::cout << "print() #" << boost::this_thread::get_id() << std::endl;
    std::cout << "hello " << i << std::endl;
    boost::this_thread::sleep(boost::posix_time::seconds(1));
    std::cout << "world " << i << std::endl;
}

void test_thread_pool()
{
    // 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(boost::bind(&print, i));
    }
}

void do_task(std::promise<int> &promiseObj) {
    boost::mutex::scoped_lock lock(io_mutex);
    std::cout << "Inside thread: " << std::this_thread::get_id() << std::endl;
    std::cout << "Inside thread: sleep 2 seconds... " << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    promiseObj.set_value(35);
}

void test_future()
{
    std::promise<int> promiseObj;
    std::future<int> futureObj = promiseObj.get_future();
    std::cout << "create thread..." << std::endl;
    std::thread th(do_task, std::ref(promiseObj));

    std::cout << "futureObj.get() block main thread." << std::endl;
    std::cout << futureObj.get() << std::endl;

    th.join();
    std::cout << "after join" << std::endl;
}

/*
std::bind
The pre bound parameters of bind need to be passed into specific variables or values. For the pre bound parameters, pass by value is used
For parameters that are not bound in advance, you need to pass STD:: placeholders in and start from_1and increase them in turn. The placeholder is pass by reference;
*/

int main(int argc, char* argv[])
{
    //test_thread();
    //test_thread_pool();
    test_future();
    return 0;
}

Reference

  • boost thread pool example

History

  • 20180523: created.

Copyright

  • Post author: kezunlin
  • Post link: https://kezunlin.me/post/f241bd30/
  • Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.