我已经实现了自己的实验性协程等待者对象来掌握等待者的基本原理。 我调用的协程在我的示例中为 foo 。在await_suspend方法中,我调用了一个线程,并且该线程执行一个作业,因此在作业结束时它将恢复等待者。
然而,即使我用 unique_ptr 控制了 thread 的生命周期,并控制了等待解构中的可连接,不知何故,handle.resume 也会生成段错误。
最后但并非最不重要的一点是,当我使用 jthread 而不是 thread 时,它工作得很好。 我无法弄清楚这里缺少什么。
#include <coroutine>
#include <iostream>
#include <thread>
struct ReturnObject {
struct promise_type {
ReturnObject get_return_object() {
auto handle = std::coroutine_handle<promise_type>::from_promise(*this);
return ReturnObject{handle};
}
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() {
}
// void return_void() noexcept {
// }
void return_value(int val) noexcept {
this->value = val;
}
std::suspend_always yield_value(int val) {
this->value = val;
return std::suspend_always{};
}
double get_value() const noexcept { return value; }
void set_value(double val) noexcept { value = val; }
private:
double value{3.14};
};
std::coroutine_handle<promise_type> h_;
ReturnObject(std::coroutine_handle<promise_type> h) : h_{h} {
}
operator std::coroutine_handle<promise_type>() { return h_; }
int get_value() const {
return h_.promise().get_value();
}
~ReturnObject() {
h_.destroy();
}
};
void do_work(std::coroutine_handle<ReturnObject::promise_type>& h) {
std::cout << "do_work\n";
h.resume();
}
struct SuspendAlways {
void await_suspend(std::coroutine_handle<ReturnObject::promise_type> h) {
std::cout << "await suspend\n";
th = std::make_unique<std::thread>(do_work, std::ref(h)); //(1)
//std::jthread (&SuspendAlways::do_work, this, std::ref(h)); //(2)
}
void await_resume() {
std::cout << "await_resume\n";
}
bool await_ready() const noexcept { return false; }
~SuspendAlways() {
std::cout << "~SuspendAlways\n";
if (th->joinable()) th->join();//(1)
}
std::unique_ptr< std::thread> th;//(1)
};
ReturnObject foo() {
std::cout << "1. Hello World!\n";
co_await SuspendAlways{};
std::cout << "2. Hello World!\n";
}
int main(int argc, char **argv) {
auto ret = foo();
using namespace std::chrono_literals;
std::this_thread::sleep_for(5000ms);
std::cout << std::boolalpha << ret.h_.done() << std::endl;
}
std::thread
的析构函数将终止程序。 std::jthread
加入销毁而不是终止程序。