运行 在 std::future 中循环直到破坏——惯用的方式?
Run loop in `std::future` until destruction - idiomatic way?
我想要一个成员std::future<void>
在一个循环中不断调用一个函数,直到父对象被销毁。
我目前的解决方案是用布尔标志将未来包装在 class 中,并在销毁时将标志设置为 false。
class Wrapper
{
std::future<void> fut;
bool wrapperAlive{true};
public:
Wrapper() : fut{std::async(std::launch::async, [this]
{
while(wrapperAlive) doSomething();
})} { }
~Wrapper()
{
wrapperAlive = false;
}
};
有没有更惯用的方法来做到这一点?
这是您的代码的无数据争用版本:
class Wrapper {
std::atomic<bool> wrapperAlive{true}; // construct flag first!
std::future<void> fut;
public:
Wrapper() :
fut{std::async(std::launch::async, [this]
{
while(wrapperAlive)
doSomething();
}
)}
{}
~Wrapper() {
wrapperAlive = false;
fut.get(); // block, so it sees wrapperAlive before it is destroyed.
}
};
接下来我要做的是写:
template<class F>
struct repeat_async_t {
F f;
// ...
};
using repeat_async = repeat_async_t<std::function<void()>>;
template<class F>
repeat_async_t<std::decay_t<F>> make_repeat_async(F&&f){
return {std::forward<F>(f)};
}
需要一个永远重复的任务,并将其捆绑在那里,而不是将流逻辑与执行的逻辑混合。
在这一点上,我们可能想要添加一个中止方法。
最后,忙循环线程很少是个好主意。所以我们会添加某种等待更多数据使用的系统。
它最终看起来与您的代码有很大不同。
我想要一个成员std::future<void>
在一个循环中不断调用一个函数,直到父对象被销毁。
我目前的解决方案是用布尔标志将未来包装在 class 中,并在销毁时将标志设置为 false。
class Wrapper
{
std::future<void> fut;
bool wrapperAlive{true};
public:
Wrapper() : fut{std::async(std::launch::async, [this]
{
while(wrapperAlive) doSomething();
})} { }
~Wrapper()
{
wrapperAlive = false;
}
};
有没有更惯用的方法来做到这一点?
这是您的代码的无数据争用版本:
class Wrapper {
std::atomic<bool> wrapperAlive{true}; // construct flag first!
std::future<void> fut;
public:
Wrapper() :
fut{std::async(std::launch::async, [this]
{
while(wrapperAlive)
doSomething();
}
)}
{}
~Wrapper() {
wrapperAlive = false;
fut.get(); // block, so it sees wrapperAlive before it is destroyed.
}
};
接下来我要做的是写:
template<class F>
struct repeat_async_t {
F f;
// ...
};
using repeat_async = repeat_async_t<std::function<void()>>;
template<class F>
repeat_async_t<std::decay_t<F>> make_repeat_async(F&&f){
return {std::forward<F>(f)};
}
需要一个永远重复的任务,并将其捆绑在那里,而不是将流逻辑与执行的逻辑混合。
在这一点上,我们可能想要添加一个中止方法。
最后,忙循环线程很少是个好主意。所以我们会添加某种等待更多数据使用的系统。
它最终看起来与您的代码有很大不同。