[英]Is there any method that causes whole stack frame unwinding in C++? (except using exception)
我一直在寫一個延續 - 特定的,協程 - 庫。 它類似於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庫以獲取示例解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.