gpt4 book ai didi

C++20 协程,await_resume 返回左值,段错误

转载 作者:行者123 更新时间:2023-12-05 06:01:57 29 4
gpt4 key购买 nike

正在发生

我想将仅移动数据存储到promise_type,并在协程中获取它。我尝试从 await_resume() 返回返回左值。结果编译成功,但执行时出现Segmentation fault

我该如何改进?


环境

  • 操作系统:WSL2 Ubuntu 20.04
  • 编译器:gcc 10.3
  • 命令:g++ -std=c++20 -fcoroutines main.cpp

代码

主要.cpp:

#include <iostream>
#include <coroutine>
#include <memory>

struct task
{
struct promise_type
{
using data_type = std::unique_ptr<int>;

task get_return_object() noexcept
{
return task(std::coroutine_handle<promise_type>::from_promise(*this));
}
std::suspend_never initial_suspend() const noexcept { return {}; }
void unhandled_exception() {}
std::suspend_always final_suspend() const noexcept { return {}; }

data_type data; // my data
};

void set_data(promise_type::data_type&& data) // [2] set my data
{
handle.promise().data = std::forward<promise_type::data_type>(data);
}

void resume()
{
handle.resume();
}

task(std::coroutine_handle<promise_type> handle) : handle(handle) {}

private:
std::coroutine_handle<promise_type> handle;
};

struct awaitalbe
{
bool await_ready() { return true; }
void await_suspend(std::coroutine_handle<task::promise_type> handle) { this->handle = handle; }
task::promise_type::data_type&& await_resume()
{
return std::move(handle.promise().data); // [3] get my data
}

std::coroutine_handle<task::promise_type> handle;
};

task f()
{
auto p2 = co_await awaitalbe{}; // [4] Segmentation fault here. after [3]
std::cout << (*p2) << std::endl;
}

int main(int argc, char* argv[])
{
auto task1 = f();

task::promise_type::data_type p1 = std::make_unique<task::promise_type::data_type::element_type>(10);
task1.set_data(std::move(p1)); // [1] set my data

task1.resume();
return 0;
}

最佳答案

在您的等待结构中,您有:

bool await_ready() { return true; }

需要说明的是,await_ready 是一种用来判断等待对象对应的结果是否就绪的机制。如果准备就绪,那么真的没有充分的理由暂停调用协程(即 co_await 可等待的协程)并等待结果 - 只需调用 await_resume检索结果。

它允许你做类似的事情:

bool await_ready() {
if (will_read_block()) {
return false;
}
read_some_data_from_file();
return true;
}

这样非阻塞读取将同步完成。

在你的例子中,你总是返回 true。这告诉运行时:当协程等待 awaitable 时,永远不要暂停该协程并直接调用 await_resume,跳过暂停和 await_suspend。实际上,如果您在 await_suspend 中的 await_suspend 中设置断点(如果您的调试器不喜欢协程,则使用打印语句),您会发现它永远不会被调用。因此,您实际上从未将任何东西分配给 awaitable 结构中的 handle 成员,当您尝试从中获取 promise 时会导致未定义的行为。

解决方案:从await_ready返回false即可。

关于C++20 协程,await_resume 返回左值,段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67078636/

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