当future离开作用域时,线程要去哪里?
Where is the thread going when a future leaves scope?
对于线程,我知道terminate()
在线程变量离开作用域时被调用:
size_t fibrec(size_t n) {
return n<2 ? 1 : fibrec(n-2)+fibrec(n-1);
}
int main() {
std::thread th{ fibrec, 35 };
// no join here
} // ~th will call terminate().
th
的析构函数将在terminate()
离开作用域时调用它。
那么future
s呢?他们运行的线程在哪里?它是分离的吗?它是如何结束的?
#include <iostream>
#include <future> // async
using namespace std;
size_t fibrec(size_t n) {
return n<2 ? 1 : fibrec(n-2)+fibrec(n-1);
}
struct Fibrec {
size_t operator()(size_t n) { return fibrec(n); }
const size_t name_;
Fibrec(size_t name) : name_(name) {}
~Fibrec() { cerr << "~"<<name_<< endl; }
};
void execit() {
auto f1 = async( Fibrec{33}, 33 );
auto f2 = async( Fibrec{34}, 34 );
// no fx.get() here !!!
}; // ~f1, ~f2, but no terminate()! Where do the threads go?
int main() {
auto f0 = async( Fibrec{35}, 35 );
execit();
cerr << "fib(35)= " << f0.get() << endl;
}
当execit()
不存在时,f1
和f2
的期货将被销毁。但是他们的线程应该还在运行吗?当然,会调用Fibrec
的析构函数。但是线程去哪里了?程序没有崩溃,所以我猜,这变成了连接?或者可能是超然的?或者它们被停止或取消了?我相信这在c++ 11中不是很容易做到的吧?
future
是异步操作的结果,它本身不是一个线程。async
函数生成一个新线程来进行计算,当计算完成后,结果被写入future
对象。
根据实现的策略,您将不得不在将来调用.get()
或.wait()
来获得结果。调用该方法将在线程上完成该工作,该线程在
如果策略为
std::launch::async
,则在其上运行INVOKE(fff,xyz…)自己的线程。返回的std::future将在执行以下操作时准备好线程已完成,并且将保存返回值或异常由函数调用抛出。最后一个未来的析构函数对象的异步状态关联Std::future将阻塞,直到future准备好。如果策略是
std::launch::deferred
,那么fff和xyz…存储在作为延迟函数调用返回的std::future中。第一个在共享的future上调用wait()或get()成员函数相同的关联状态将执行INVOKE(fff,xyz…)在调用wait()或get()的线程上同步执行。
这是一个非常基本的std::async
实现(没有任务池或std::launch
的东西):
template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args )
{
std::packged_task<F(Args...)> task(std::forward<F>(f), std::forward<Args>(args)...);
auto ret = task.get_future();
std::thread t(std::move(task));
t.detach();
return ret;
}
你可以看到实际的计算是在一个分离的线程中完成的。未来只是一个同步对象。std::packaged_task
只是std::promise
set_value
/set_exception
逻辑的另一个包装。
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- future::wait() 是否与 async() 执行线程的完成同步?
- 线程是否真的在调用 std::future::get() 后启动
- std::future 或 std::shared_future 等待多个线程
- 异常不会使用boost :: future/boost :: Promise跨线程正确传播
- 固定到内核的 FIFO 线程上的 std::p romise::set_value 不会唤醒 std::future
- 在 std::future 上多次从多个线程调用 wait() 是否安全
- std::future.get() 多个调用(来自不同的线程)
- 为什么即使我使用 std::future::get 也需要加入线程
- 当future离开作用域时,线程要去哪里?
- 在多线程库中转换future