为什么setjmp没有保存堆栈?

时间:2011-08-28 22:21:57

标签: c++ longjmp setjmp

为什么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;
}

除此之外,代码将从主要功能来回跳转到功能,并且每次都打印增加的数字 实际发生的是,它会无限次地打印0然后1。就好像当它跳回到函数中时,堆栈被重置为默认值。它为什么这样做?有没有什么方法可以让它保存堆栈呢? 我知道setjmplongjmp在编码风格和可读代码时甚至比goto更差,但我现在正在尝试,而且这段代码可能永远不会看到可用的应用程序。

1 个答案:

答案 0 :(得分:2)

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

或者你可以使用像Russ Cox的libtask(http://swtch.com/libtask/)这样的东西来帮助你。或者如果你想自己做,你应该看看libtask代码(也可以通过该链接获得)。它非常容易阅读,因此它是一个很好的资源。