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

C++ 使用boost线程池执行器提交方法,c++,multithreading,boost,C++,Multithreading,Boost,我正在努力学习boost线程池。 不工作,希望在这里找到帮助 下面的代码中发生了一些奇怪的事情 创建执行者ea和 使用async启动它,直到完成提交的函数 然后将其他函数提交给第一个执行器ea,但我不启动它 然后创建另一个相同类型(basic\u thread\u pool)和不同线程数(1)的执行器ea3 并使用async启动第二个执行器ea3 它首先执行第一个执行器ea,然后执行第二个执行器ea3 虽然我只是使用ea3作为async的参数 为什么会发生这种情况?如何防止执行ea 无名范围

我正在努力学习boost线程池。 不工作,希望在这里找到帮助

下面的代码中发生了一些奇怪的事情

  • 创建执行者
    ea
  • 使用
    async
    启动它,直到完成提交的函数
  • 然后将其他函数提交给第一个执行器
    ea
    ,但我不启动它
  • 然后创建另一个相同类型(
    basic\u thread\u pool
    )和不同线程数(1)的执行器
    ea3
  • 并使用
    async
    启动第二个执行器
    ea3
  • 它首先执行第一个执行器
    ea
    ,然后执行第二个执行器
    ea3
虽然我只是使用
ea3
作为
async
的参数

为什么会发生这种情况?如何防止执行
ea

无名范围有影响吗

#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();
}
#定义BOOST_线程_版本4
#定义BOOST\u线程\u提供\u执行器
#定义BOOST\u线程\u使用\u日志\u线程\u ID
#定义BOOST\u线程\u队列\u弃用\u旧
#包含//用于词法转换
#包括

#包括//用于BOOST\u CONTEXTOF、caller\u context\t、operator 1。最小代码2。工作守则3。失去毫无意义的锁定和跟踪。(参考之前帖子上的评论;我很高兴没有投反对票,但这完全值得投反对票。你会想修复/删除)我编辑了它…我认为这种行为与硬件实际线程数和作为参数给出的线程数有关…如果参数“线程数”高于硬件线程,然后隐藏的东西重用线程…在这种情况下,此实际线程上的挂起工作是前一个执行器的工作,因此在我启动新线程池时开始执行…这是一个猜测,但我不知道如何确认它是否。。。现在您已经两次列出了相同的大型代码,但第一次截取了42行(208行中的42行)“随机”代码?另外,第二个版本包括139(!!)个空(注释)行。我将尝试一下,如果我现在能理解这个“简化”的代码,我已经将示例修改到不到50%(删除锁定问题和未使用的代码)。如果本周末晚些时候我有时间,我可能会看看由此产生的问题。我尝试了你的代码,它给出了相同的问题…我认为它是相同的代码:)…虽然我不知道trace()但它似乎是非常有效的模板…我想知道你是怎么想的…非常感谢你的帮助和耐心