为什么没有std::future::try_wait()
Why there is no std::future::try_wait()?
鉴于有std::future::wait_for/until()
,我不明白为什么没有std::future::try_wait()
。我目前正在编写一个生产者-消费者示例,我想使用 std::future
作为向消费者线程发出返回信号的便捷方式。我的消费者代码就像
void consume(std::future<void>& stop) {
while (!stop.try_wait()) { // alas, no such method
// try consuming an item in queue
}
}
我想用零持续时间wait_for()
来模拟try_wait()
,这真的很丑陋。作为一个附带问题:还有其他方便的方法来指示消费者线程返回吗?
>std::experimental::future
添加了.is_ready()
和.then( F )
方法。
is_ready
可能是您的try_wait
(没有超时(。
如前所述,wait_for
为您提供了try_wait
在实践中的功能。
std::future
不是设计为信号机制,即使它可以用作信号机制。 如果您想要一个信令机制,请使用条件变量、互斥锁和存储信号状态的状态(可能将它们组合在一起(创建一个。
struct state {
bool stop = false;
unsigned some_value = 7;
friend auto as_tie( state const& s ) {
return std::tie(s.stop, s.some_value);
}
friend bool operator==( state const& lhs, state const& rhs ) {
return as_tie(lhs)==as_tie(rhs);
}
};
template<class State, class Cmp=std::equal<State>>
struct condition_state {
// gets a copy of the current state:
State get_state() const {
auto l = lock();
return state;
}
// Returns a state that is different than in:
State next_state(State const& in) const {
auto l = lock();
cv.wait( l, [&]{ return !Cmp{}(in, state); } );
return state;
}
// runs f on the state if it changes from old.
// does this atomically in a mutex, so be careful.
template<class F>
auto consume_state( F&& f, State old ) const {
auto l = lock();
cv.wait( l, [&]{ return !Cmp{}(old, state); } );
return std::forward<F>(f)( state );
}
// runs f on the state if it changes:
template<class F>
auto consume_state( F&& f ) const {
return consume_state( std::forward<F>(f), state );
}
// calls f on the state, then notifies everyone to check if
// it has changed:
template<class F>
void change_state( F&& f ) {
{
auto l = lock();
std::forward<F>(f)( state );
}
cv.notify_all();
}
// Sets the value of state to in
void set_state( State in ) {
change_state( [&](State& state) {
state = std::move(in);
} );
}
private:
auto lock() const { return std::unique_lock<std::mutex>(m); }
mutable std::mutex m;
std::condition_variable cv;
State state;
};
例如,假设我们的State
是就绪任务的向量和一个表示"中止"的布尔值:
struct tasks_todo {
std::deque< std::function<void()> > todo;
bool abort = false;
friend bool operator==()( tasks_todo const& lhs, tasks_todo const& rhs ) {
if (lhs.abort != rhs.abort) return false;
if (lhs.todo.size() != rhs.todo.size()) return false;
return true;
}
};
然后我们可以按如下方式编写我们的队列:
struct task_queue {
void add_task( std::function<void()> task ) {
tasks.change_state( [&](auto& tasks) { tasks.todo.push_back(std::move(task)); } );
}
void shutdown() {
tasks.change_state( [&](auto& tasks) { tasks.abort = true; } );
}
std::function<void()> pop_task() {
return tasks.consume_state(
[&](auto& tasks)->std::function<void()> {
if (tasks.abort) return {};
if (tasks.todo.empty()) return {}; // should be impossible
auto r = tasks.front();
tasks.pop_front();
return r;
},
{} // non-aborted empty queue
);
}
private:
condition_state<task_todo> tasks;
};
或诸如此类。
由于 std::future::wait_for 不可用,因此可以指定自己的超时例程,如代码片段所示:
void even(int n,promise<bool> p)
{
this_thread::sleep_for(chrono::milliseconds(500ms)); //set milliseconds(10ms) to display result
p.set_value( n%2 == 0?true:false);
}
int main()
{
promise<bool> p;
future<bool> f =p.get_future();
int n = 100;
std::chrono::system_clock::time_point tp1 = std::chrono::system_clock::now() ;
thread t([&](){ even(n,move(p)); });
auto span = std::chrono::milliseconds(200ms);
std::future_status s;
do
{
s =f.wait_for(std::chrono::seconds(0));
// do something
}
while( std::chrono::system_clock::now() < (tp1 + span) );
if( s==future_status::ready)
std::cout << "result is " << (f.get()? "Even": "Odd") << 'n';
else
std::cout << "timeout " << 'n';
t.join();
}
相关文章:
- std::condition_variable::wait()如何评估给定的谓词
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- std::memory_order for std::atomic:<T>:wait
- C++ Python "try: except:"版本
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- 编译器是否必须始终删除 try-catch 块(如果它被证明是非抛出的)
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 当无法进行RAII时,如何在C++中"try/finally"?
- 我可以使用 try catch 语句来捕获任何错误而不是具体错误吗?
- std::future::get()或std::future::wait()是std::thread::join()的替
- 在大型应用程序的main上使用try-catch
- RapidXML 节点在 try catch 块中具有正确的值,但它在块外为 nullptr
- 提取 try-catch 时出现运行时错误
- C++:在"try"外部创建的类型会导致错误,但在内部不会
- std::unique_ptr 在 try-catch 块中未捕获取消引用异常
- 何时删除 try-catch 块中的指针
- 在 while 循环中使用 std::condition_variable::wait 是否正确
- 是否有理由大多数/所有 try-catch 示例只对 throw 语句使用 void 子函数
- future::wait() 是否与 async() 执行线程的完成同步?