如题,我正在用 cpp 写一个线程池的 submit 函数,为了可以让用户可以异步的获取到函数执行的返回值,我使用了 future 和 promise 特性,一部分代码如下:
template <typename Fn, typename... Args, typename HasRet, typename Redundant>
::std::future<typename ::std::result_of<Fn(Args...)>::type>
ThreadPool::submit(Fn&& func, Args... args)
{
if (!running_)
{
LOGS_FATAL << "thread pool has not been initialized";
}
using RetType = typename ::std::result_of<Fn(Args...)>::type;
LockGuardType lock(mutex_);
auto promise = ::std::make_shared<::std::promise<RetType>>();
auto future = promise->get_future();
::std::function<RetType()> tmpTask = ::std::bind(::std::forward<Fn>(func), ::std::forward<Args>(args)...);
1 ) TaskType task = [t = ::std::move(tmpTask), promise]() mutable
{
2 ) assert(promise.use_count() == 1);
promise->set_value(t());
};
3 ) assert(promise.use_count() == 2);
......
return future;
}
1 )处我用的 lambda 是值捕获 promise,3 )处的 use_count 总为 2 这没问题,现在的问题不知为什么 2 )处的 use_count 却不稳定,有时为 3 ,有时为 1 ? 下面为测试代码:
TEST_F(ThreadPoolTest, SubmitHasRetval)
{
::std::function<int32_t ()> f = []() -> int32_t
{
return 5;
};
auto future1 = threadPool->submit(f);
future1.wait();
ASSERT_EQ(future1.get(), 5);
auto future2 = threadPool->submit(::std::move(f));
future2.wait();
ASSERT_EQ(future2.get(), 5);
}
debug 模式下正常结果为:
2022-05-10 11:09:44.942 [9924] DEBUG ThreadPool.cpp:111 - thread pool init success
2022-05-10 11:09:44.943 [9924] DEBUG ThreadPool.cpp:128 - thread pool has been shutdown
错误结果为:
... Assertion `promise.use_count() == 1' failed.
2022-05-10 11:17:26.951 [10115] DEBUG ThreadPool.cpp:111 - thread pool init success
感谢大佬们看完我这丑陋的代码。。。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.