使用boost线程池执行器提交方法

时间:2018-03-23 15:41:25

标签: c++ multithreading boost

我正在尝试学习提升线程池。 不工作,希望在这里找到帮助。

当我

时,以下代码会发生一些奇怪的事情
  • 创建执行者ea
  • 使用async启动它,直到完成提交的功能
  • 然后向第一位执行人ea提交其他功能,但我不会启动它,
  • 然后再创建相同类型(ea3)和不同线程数(1)的另一个执行者basic_thread_pool
  • 并使用ea3
  • 启动第二个执行者async
  • 首先执行第一个执行者ea,然后执行第二个执行者ea3

虽然我只使用ea3作为async的参数。

为什么会这样?以及如何阻止执行ea

无名范围是否有效?

Live On Coliru

#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#define BOOST_THREAD_USES_LOG_THREAD_ID
#define BOOST_THREAD_QUEUE_DEPRECATE_OLD

#include <boost/lexical_cast.hpp>                        // for lexical_cast
#include <boost/thread.hpp>
#include <boost/thread/caller_context.hpp>               // for BOOST_CONTEXTOF, caller_context_t, operator<<
#include <boost/thread/executors/basic_thread_pool.hpp>  // for basic_thread_pool
#include <boost/thread/executors/executor.hpp>           // for executor
#include <boost/thread/executors/executor_adaptor.hpp>   // for executor_adaptor

#include <iostream> // for operator<<, cout, endl, ..
#include <chrono>   // for operator "" ms, operator "" s
#include <thread>   // for sleep_for
#include <string>
#include <vector>

static boost::mutex stdout_mutex;
template <typename A, typename B = std::string> static inline void trace(A const &a, B const& b = "") {
    boost::lock_guard<boost::mutex> lock(stdout_mutex);
    std::cout << a << b << std::endl;
}

static inline void trace(boost::caller_context_t const &ctx) { trace(boost::lexical_cast<std::string>(ctx)); }

namespace {
    using namespace std::chrono_literals;
    using std::this_thread::sleep_for;
    void p1() { trace(BOOST_CONTEXTOF); sleep_for(20ms); } 
    void p2() { trace(BOOST_CONTEXTOF); sleep_for(1s); } 
    int  f1() { trace(BOOST_CONTEXTOF); sleep_for(100ms); return 1; } 
}

void submit_some(boost::executor &tp) {
    for (int i = 0; i < 3; ++i) { tp.submit(p2); }
    for (int i = 0; i < 3; ++i) { tp.submit(p1); }
}

int test_executor_adaptor() {
    trace(BOOST_CONTEXTOF);
    try {
        boost::executor_adaptor<boost::basic_thread_pool> ea(4);
        trace(BOOST_CONTEXTOF);

        submit_some(ea);
        {
            boost::future<int> t1 = boost::async(ea, &f1);
            trace(BOOST_CONTEXTOF);
            trace(" t1= ", t1.get()); // problem unknown on running showing thread result before running code
            std::vector<boost::future<int> > vt1;
            for (int i = 0; i < 4; i++) {
                vt1.push_back(boost::async(ea, &f1)); // here async starts all closures already submitted to ea
                // then submit f1 to all threads in ea to work
                // asynchronusly so end result will be 7 already submitted
                // and 4 more f1 and return futures to only the last 4 f1
                // which is submitted by async
            }

            for (auto &e : vt1) {
                auto e_value = e.get();
                trace("vt1 e_value = ", e_value);
            }
        }

        submit_some(ea);
        {
            boost::executor_adaptor<boost::basic_thread_pool> ea3(1);
            boost::future<int> t1 = boost::async(ea3, &f1);

            std::vector<boost::future<int> > vt1;
            for (int i = 0; i < 4; i++) {
                vt1.push_back(
                        boost::async(ea3, &f1)); // here async starts all closures already submitted to ea
                // then submit f1 to all threads in ea to work
                // asynchronusly so end result will be 7 already submitted
                // and 4 more f1 and return futures to only the last 4 f1
                // which is submitted by async
            }

            for (auto &e : vt1) {
                trace("vt1 e_value = ", e.get());
            }
        }
     } 
    catch (std::exception &ex) { trace("ERROR= ", ex.what()); return 1; }
    catch (...)                { trace("UNKNOWN EXCEPTION"); return 2;  } 

    trace(BOOST_CONTEXTOF);
    return 0;
}

int main() {
    trace(BOOST_CONTEXTOF);
    return test_executor_adaptor();
}

我认为basic_thread_pool使用事件循环,
这个事件循环是单例,
因此,当我定义另一个basic_thread_pool时,它只使用相同的事件循环,反过来当获得期货时,它会运行事件循环上的所有任务,包括其他线程池的任务,
这是猜测,但我无法从impl代码中找到证据 如果这个猜测是正确的,我如何为每个basic_thread_pool制作不同的事件循环 我使用msvc 14 感谢

0 个答案:

没有答案