- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我使用的是 vc2011,结果发现 std::async(std::launch::async, ...) 有点问题(有时它不会生成新线程并并行运行它们,而是重用线程并一个接一个地运行任务)。当我进行昂贵的网络调用时,这太慢了。所以我想我会编写自己的异步函数。我被卡住了,std::promise 应该放在哪里?在 1) 线程函数、2) 异步函数或 3) 调用函数中。
代码:
#include <future>
#include <thread>
#include <iostream>
#include <string>
#include <vector>
std::string thFun() {
throw std::exception("bang!");
return "val";
}
std::future<std::string> myasync(std::promise<std::string>& prms) {
//std::future<std::string> myasync() {
//std::promise<std::string> prms; //needs to outlive thread. How?
std::future<std::string> fut = prms.get_future();
std::thread th([&](){
//std::promise<std::string> prms; //need to return a future before...
try {
std::string val = thFun();
prms.set_value(val);
} catch(...) {
prms.set_exception(std::current_exception());
}
});
th.detach();
return fut;
}
int main() {
std::promise<std::string> prms; //I really want the promise hidden iway in the myasync func and not live here in caller code but the promise needs to outlive myasync and live as long as the thread. How do I do this?
auto fut = myasync(prms);
//auto fut = myasync(); //Exception: future already retrieved
try {
auto res = fut.get();
std::cout << "Result: " << res << std::endl;
} catch(const std::exception& exc) {
std::cout << "Exception: " << exc.what() << std::endl;
}
}
我似乎无法忘记 std::promise 需要比异步函数长寿(并且与线程一样长)的事实,因此 promise 不能作为异步函数中的局部变量存在。但是 std::promise 也不应该存在于调用者代码中,因为调用者只需要知道 future 。而且我不知道如何在线程函数中实现 promise ,因为异步需要在调用线程函数之前返回 future 。我在这个问题上摸不着头脑。
有人有什么想法吗?
编辑:我在这里强调这一点,因为顶部评论有点误导。虽然 std::asycn 的默认值允许为 dererred 模式,但当显式设置 std::launch::async 的启动策略时,它必须表现得“好像”线程被生成并立即运行(参见 en 中的措辞.cppreference.com/w/cpp/thread/async)。请参阅 pastebin.com/5dWCjjNY 中的示例,了解这不是 vs20011 中看到的行为的一种情况。该解决方案效果很好,将我的实际应用程序加速了 10 倍。
编辑 2:微软修复了这个错误。更多信息在这里:https://connect.microsoft.com/VisualStudio/feedback/details/735731/std-async-std-launch-async-does-not-behave-as-std-thread
最佳答案
这是一种解决方案:
future<string> myasync()
{
auto prms = make_shared<promise<string>> ();
future<string> fut = prms->get_future();
thread th([=](){
try {
string val = thFun();
// ...
prms->set_value(val);
} catch(...) {
prms->set_exception(current_exception());
}
});
th.detach();
return fut;
}
在堆上分配 promise,然后按值传递 [=]
一个 shared_ptr 到 lambda。
关于c++ - 用自己的版本替换 std::async 但 std::promise 应该住在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10184377/
我是一名优秀的程序员,十分优秀!