gpt4 book ai didi

c++ - 为什么没有 std::future::try_wait()?

转载 作者:行者123 更新时间:2023-11-30 03:25:12 36 4
gpt4 key购买 nike

鉴于有 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 是一个准备好的任务 vector 和一个表示“中止”的 bool 值:

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;
};

或类似的东西。

关于c++ - 为什么没有 std::future::try_wait()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49144543/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com