gpt4 book ai didi

c++ - 协程 TS 2017 的实现示例

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:59 25 4
gpt4 key购买 nike

C++ coroutines TS (2017) , 有一个等待对象的例子。

 template <class Rep, class Period>
auto operator co_await(std::chrono::duration<Rep, Period> d) {
struct awaiter {
std::chrono::system_clock::duration duration;
...
awaiter(std::chrono::system_clock::duration d) : duration(d){}
bool await_ready() const { return duration.count() <= 0; }
void await_resume() {}
void await_suspend(std::experimental::coroutine_handle<> h){...}
};

return awaiter{d};
}

using namespace std::chrono;
my_future<int> h();
my_future<void> g() {
std::cout << "just about go to sleep...\n";
co_await 10ms;
std::cout << "resumed\n";
co_await h();
}

与典型的 StackOverflow 问题一样,它不会编译。默默骂了一阵子后,决定把它做成一个【MCVE】——用来学习。下面的代码在启用/await 的 VC++17 上编译和运行。我认为它可能大致符合 TS 作者的意图。 las,它使用了一个分离的线程。很难看出如何通过 joinfuture::getsignal_all_at_thread_exit() 或 ...

例如,join 不能添加到awaiter 的析构函数中。在派生线程中,h.resume() 导致等待者对象被移动到派生线程中,并在那里调用其(默认)构造函数。因此,析构函数与构造函数在不同的线程中被调用。

问题,除了“这是 TS 的意图吗?”之外,“能否以合理经济的方式改进它以趋向于悬挂线程?”(如果是的话怎么办?)

#include <experimental/coroutine>
#include <future>
#include <thread>

namespace xtd = std::experimental;

template <class Rep, class Period>
auto operator co_await(std::chrono::duration<Rep, Period> dur) {

struct awaiter {
using clock = std::chrono::high_resolution_clock;
clock::time_point resume_time;

awaiter(clock::duration dur) : resume_time(clock::now()+dur) {}

bool await_ready() { return resume_time <= clock::now(); }

void await_suspend(xtd::coroutine_handle<> h) {
std::thread([=]() {
std::this_thread::sleep_until(resume_time);
h.resume(); // destructs the obj, which has been std::move()'d
}).detach(); // Detach scares me.
}
void await_resume() {}
};

return awaiter{ dur };
}

using namespace std::chrono;

std::future<int> g() {
co_await 4000ms;
co_return 86;
}


template<typename R>
bool is_ready(std::future<R> const& f)
{ return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }

int main() {
using std::cout;
auto gg = g();
cout << "Doing stuff in main, while coroutine is suspended...\n";
std::this_thread::sleep_for(1000ms);
if (!is_ready(gg)) {
cout << "La lala, lala, lala...\n";
std::this_thread::sleep_for(1500ms);
}

cout << "Whew! Done. Getting co_return now...\n";
auto ret = gg.get();
cout << "coroutine resumed and co_returned " << ret << '\n';
system("pause");
return ret;
}

最佳答案

Can this be improved, in a reasonably economical way, to tend to the dangling thread?

您可以使用“线程池”实现,而不是按需分离线程。

这是玩具示例: https://gist.github.com/yohhoy/a5ec6d4aeeb4c60d3e4f3adfd1df9ebf

关于c++ - 协程 TS 2017 的实现示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49640336/

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