为什么 setjmp 不保存堆栈?

发布于 2024-12-02 05:36:36 字数 760 浏览 0 评论 0原文

为什么 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 到函数来回跳转,然后每次都打印递增的数字。
实际发生的情况是,它无限次打印 0,然后打印 1。就好像当它跳回函数时堆栈被重置为默认值。它为什么这样做?有什么方法可以让它也保存堆栈吗?
我知道在编码风格和可读代码方面 setjmplongjmp 甚至比 goto 更糟糕,但我现在正在尝试,而这个代码可能永远不会成为可用的应用程序。

Why isn't setjmp saving the stack?
Consider the following code:

#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;
}

What I except is that the code will jump back and forth from main to the function and back printing increasing number every time.
What actually happens is that it prints 0 and then 1 infinite number of times. it is as if when it jumps back into the function the stack is reset to defaults. why is it doing it? is there any way I can make it save the stack too?
I know setjmp and longjmp are even worse than goto when it comes to coding style and readable code, but I am experimenting right now, and this code will probably never see the light of a usable application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

递刀给你 2024-12-09 05:36:36

因为不幸的是 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 代码(也可以通过该链接获得)。它很容易阅读,因此是一个很好的资源。

Because unfortunately thats not how setjmp works. setjmp copies the current instruction pointer and register set into the jump buffer but it does not copy the stack (obviously be cause the stack is huge). It looks like you want to use some kind of coroutine based techniques. If you want to do this yourself checkout the ucontext procedured (ucontext.h) http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?ucontext.h+3 they will help you to allocate and manage additionaly thread stacks.

or you could use something like Russ Cox's libtask (http://swtch.com/libtask/) which will help do this for you. Or if you want to do it yourself you should take a look at the libtask code (also available through that link). It's pretty easy to read so its a good resource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文