为什么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
。就好像当它跳回到函数中时,堆栈被重置为默认值。它为什么这样做?有没有什么方法可以让它保存堆栈呢?
我知道setjmp
和longjmp
在编码风格和可读代码时甚至比goto
更差,但我现在正在尝试,而且这段代码可能永远不会看到可用的应用程序。
答案 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代码(也可以通过该链接获得)。它非常容易阅读,因此它是一个很好的资源。