gpt4 book ai didi

c++ - 在 C++ 中是否有任何方法导致整个堆栈帧展开? (除了使用异常(exception))

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

我一直在写一个延续——特别是协程——库。它类似于 std::thread(除了它是协作的)——每个执行上下文都在延续对象中表示。

问题是关于连续对象销毁。如果在执行上下文尚未正常退出时调用延续对象的 dtor,则应通过销毁对象的上下文强制关闭它。

这样,堆栈帧中的每个 C++ 对象都不会被正确销毁。这对任何人来说都不是一个愉快的情况 - 所以我决定找到一个解决方案。

起初,我想像下面这样使用异常来展开堆栈框架。 (请注意,下面只是有缺陷的伪代码。)

coroutine::~coroutine()
{
status = FORCED_EXIT;
switch_to(*this);
}

void coroutine::yield(coroutine& other_coroutine)
{
// switch to other context, halt until invocation by other context
switch_to(other_coroutine);

if (status_ != FORCED_EXIT) {
return; // resume
} else {
throw ContextClosingException;
}
}

void coroutine::entrypoint()
{
try {
entry_function_();
} catch(ContextClosingException& e) {
switch_to(caller_coroutine);
}
}

但是,我发现了一些严重的缺陷。任何如下“吞噬异常”的用户代码将完全打破协同调度的假设。

try {
...
} catch(...) { // ContextClosingException
// do nothing, just swallow exception.
}

所以我需要找到其他方法来调用堆栈展开(或任何其他方法来在延续中销毁堆栈对象)。符合标准的方式会很好——但是延续实现本身依赖于平台特定的 API,因此不可移植的方式是可以接受的。 (我使用的是 win32)

最佳答案

除异常外,C++ 标准中没有任何内容允许展开堆栈。协程(或对协程的支持)可能会在 C++11 之后提出(在 Going Native session 期间讨论过)。

您将不得不使用特定于操作系统的 C 调用(如果存在但我认为不存在),但很可能您只能靠自己使用 ASM。您可以查看 boost.context 库以获取示例解决方案。

关于c++ - 在 C++ 中是否有任何方法导致整个堆栈帧展开? (除了使用异常(exception)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9286550/

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