c++ - 如何在 C++ 中使用协程实现 async_sleep?
问题描述
我试图了解 C++ 协程是如何工作的,所以我尝试实现一个async_sleep
不会阻塞的等待器:
Interleaver mycoro(std::function<void()> f1, std::function<void()> f2)
{
f1();
co_await async_sleep{2s};
f2();
}
这是完整的代码:
#include <iostream>
#include <coroutine>
#include <chrono>
#include <functional>
using namespace std;
struct Interleaver {
struct promise_type {
Interleaver get_return_object() { return {coroutine_handle<promise_type>::from_promise(*this)}; }
suspend_never initial_suspend() { return {}; }
suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() { exc_ = current_exception(); }
void return_void() { }
exception_ptr exc_;
};
operator bool() { return !handle_.done(); }
void operator()() { handle_.resume(); }
coroutine_handle<promise_type> handle_;
};
struct async_sleep {
async_sleep(chrono::seconds dur) : dur_{dur} { }
bool await_ready()
{
if (dur_ == 0s) return true;
startTime_ = chrono::steady_clock::now();
return false;
}
bool await_suspend(coroutine_handle<Interleaver::promise_type> h)
{
auto now = chrono::steady_clock::now();
auto diff = now - startTime_;
auto shouldSuspend = diff < dur_;
return shouldSuspend;
}
void await_resume() { }
chrono::seconds dur_;
chrono::steady_clock::time_point startTime_;
};
Interleaver mycoro(std::function<void()> f1, std::function<void()> f2)
{
f1();
co_await async_sleep{2s};
f2();
}
int main()
{
auto i = mycoro([] { cout << "before" << endl; },
[] { cout << "after" << endl; });
while (i) {
i();
}
}
问题是,一旦main()
函数通过调用触发协程恢复i()
,我就无法停止协程,它会在 2 秒过去之前恢复。我想要的行为是,直到 2 秒过去,协程才恢复(即使通过协程句柄恢复协程。)
我知道我可以在Interleaver
类中实现一个 API,该 API 可以验证指定的时间是否已经过去,但我不希望协程的调用者具有恢复协程以外的任何能力。
我怎样才能做到这一点?
解决方案
推荐阅读
- c++ - 在静态类函数成员中获取类对象指针
- sql-server - 选择出现两次的记录,略有不同
- reporting-services - SSRS Fetchxml SubReport 在没有返回数据时显示错误
- java - D/OkHttp: <-- HTTP FAILED: javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x64e3c938: I/O error during system call, Connection reset by peer
- angular - 使用 Angular 的原生移动应用程序的 SQLite db
- java - 带有 MongoDB 的 Java POJO 不提取数据
- python - openpyxl 无法追加列表数据类型,一直显示 TypeError: Value must be a list
- ios - 使用 Apple Pay 完成 NFC 交易后立即通过推送通知通知设备
- google-bigquery - Big Query Deduplication 查询示例说明
- f# - F# 中的结果和域设计