为什么 setjmp 不保存堆栈?

Why isn't setjmp saving the stack?

本文关键字:堆栈 保存 setjmp 为什么      更新时间:2023-10-16

为什么setjmp不保存堆栈?
考虑下面的代码:

#include <iostream>
jmp_buf Buf;
jmp_buf Buf2;
void MyFunction()
{
    for(int i = 0; i < 5; i++)
    {
        std::cout << i << std::endl;
        if(!setjmp(Buf))
            longjmp(Buf2, 1);
    }
}
int main (int argc, const char * argv[])
{
    while(true)
    {
        if(!setjmp(Buf2))
        {
            MyFunction();
            break;
        }
        longjmp(Buf, 1);
    }
    return 0;
}

我所希望的是代码将在main和函数之间来回跳转,并且每次返回递增的数字。
实际发生的是它输出01无数次。这就好像当它跳转回函数时,堆栈被重置为默认值。它为什么要这样做?有没有办法让它也保存堆栈?
我知道setjmplongjmp在编码风格和可读代码方面甚至比goto更差,但我现在正在试验,这段代码可能永远不会看到可用应用程序的光芒。

因为不幸的是setjmp不是这样工作的。Setjmp将当前指令指针和寄存器集复制到跳转缓冲区中,但它不复制堆栈(显然这是因为堆栈很大)。看起来您想使用某种基于协程的技术。如果你想自己做这件事,请检查uncontext过程(uncontext .h) http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?ucontext.h+3,它们将帮助你分配和管理额外的线程堆栈。

或者您可以使用Russ Cox的libtask (http://swtch.com/libtask/)之类的东西,它将帮助您完成此操作。或者,如果您想自己动手,您应该查看libtask代码(也可以通过该链接获得)。它很容易阅读,所以它是一个很好的资源