加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

是否有任何方法导致整个堆栈帧在C中展开? (除了使用例外)

发布时间:2020-12-16 06:58:50 所属栏目:百科 来源:网络整理
导读:我一直在写一个延续 – 特定的,协程 – 库.它类似于std :: thread(除了它是合作的) – 每个执行上下文都在continuation对象中表示. 问题是关于持续对象的破坏.如果在执行上下文没有正常退出时调用continuation对象的dtor,则应该强制它被销毁该对象的上下文关
我一直在写一个延续 – 特定的,协程 – 库.它类似于std :: thread(除了它是合作的) – 每个执行上下文都在continuation对象中表示.

问题是关于持续对象的破坏.如果在执行上下文没有正常退出时调用continuation对象的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之后提出协程(或对corountines的支持)(在Going Native会议期间谈到).

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读