将std::future
声明为mutable
是否安全(线程安全),因为其get()
函数会更改其状态。我假设它像std::mutex
一样可以安全地制成mutable
。
template <typename T>
struct S {
void query() {
m_fut = doAsyncQuery();
}
template <typename L>
void get(L lambda) const {
lambda(m_f.get());
}
mutable std::future<T> m_f;
};
答案 0 :(得分:2)
它是线程安全的吗?
不,但这没关系。
std::future
仅用于单线程,并且在设计上也不是线程安全的。在多个线程之间共享它是没有意义的。您应该只打一次get()
,然后扔掉它。
(运行附加操作并设置get()
返回的值的线程在这里不相关。该实现为您管理和隐藏了必要的同步。)
(当然,您可以将std :: future的所有权从一个线程转移到另一个线程。但是在任何给定时间,只有一个线程应该持有并使用std :: future。) >
可变吗?
是的。实际上,std::future
不能为const
,因为在附加操作完成时和调用get()
时,其状态会根据定义更改。
但是mutable
不应是此处要查找的关键字。当然,您可以使用std::future
关键字将class
包裹在struct
或mutable
中,然后创建该类的const
实例,但是您隐藏了删除了一条重要的信息(即包装器根本不是const)。 (在更复杂的类中可能有意义,但我认为具有std :: future成员的复杂类是不良设计的标志。)
相反,您也应该使此类包装器类或struct non-const:
template <typename T>
struct S {
void query() {
m_fut = doAsyncQuery();
}
template <typename L>
void get(L lambda) { // remove const here
lambda(m_f.get());
}
std::future<T> m_f; // remove mutable here
};
只要您知道S
的实例不能为const,就只能调用get
一次,并且您不应该在线程之间共享S
,你应该很安全。