是否有任何方法导致整个堆栈帧在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库以获取示例解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |