我正在尝试学习提升线程池。 不工作,希望在这里找到帮助。
当我
时,以下代码会发生一些奇怪的事情ea
和async
启动它,直到完成提交的功能ea
提交其他功能,但我不会启动它,ea3
)和不同线程数(1)的另一个执行者basic_thread_pool
ea3
,async
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();
}
我认为basic_thread_pool使用事件循环,
这个事件循环是单例,
因此,当我定义另一个basic_thread_pool时,它只使用相同的事件循环,反过来当获得期货时,它会运行事件循环上的所有任务,包括其他线程池的任务,
这是猜测,但我无法从impl代码中找到证据
如果这个猜测是正确的,我如何为每个basic_thread_pool制作不同的事件循环
我使用msvc 14
感谢