【发布时间】:2016-01-29 05:27:24
【问题描述】:
我有一个关于使用 setjmp 和 longjump 创建可以相互独立运行的函数堆栈的问题。参考this question
这里 B() 的函数堆栈似乎在 A 的堆栈之上,所以当 A 超出范围时,我尝试长跳转到 B() 代码段错误。修改后的代码是这样的
#include <stdio.h>
#include <setjmp.h>
#include <iostream>
using namespace std;
jmp_buf bufferA, bufferB;
void routineB(); // forward declaration
void routineA()
{
int r ;
printf("(A1)\n");
r = setjmp(bufferA);
if (r == 0) routineB();
printf("(A2) r=%d\n",r);
r = setjmp(bufferA);
if (r == 0) longjmp(bufferB, 20001);
printf("(A3) r=%d\n",r);
r = setjmp(bufferA);
if (r == 0) longjmp(bufferB, 20002);
printf("(A4) r=%d\n",r);
}
void routineB()
{
int r;
printf("(B1)\n");
r = setjmp(bufferB);
if (r == 0) longjmp(bufferA, 10001);
printf("(B2) r=%d\n", r);
r = setjmp(bufferB);
if (r == 0) longjmp(bufferA, 10002);
printf("(B3) r=%d\n", r);
r = setjmp(bufferB);
if (r == 0) longjmp(bufferA, 10003);
cout << "WHAT" << endl;
}
int main(int argc, char **argv)
{
routineA();
longjmp(bufferB, 123123);
return 0;
}
我在想,我们可以让每个协程(在本例中为 B 和 A)跳转回一个主函数,然后如果协程还活着,那么它们又会跳转到其中一个协程。这会起作用还是也会出现段错误,因为一些可能已死的协程堆栈位于想要运行的堆栈之上?
如果它看起来应该是段错误,那么如何在 C++ 中实现这种独立的 couroutines(当其他人死亡并且不相互依赖时可以运行)?
注意:我不想使用 swapcontext、makecontext、setcontext 和 getcontext,因为它们已被弃用。这篇文章的目的是帮助我找到这些功能的替代品
提前致谢!
【问题讨论】:
-
您不能
longjmp()进入调用堆栈中比当前执行函数更深的函数。 -
至少对于 c++(我也相信 C),引用的答案是错误的。您正在调用未定义的行为。
-
可以使用 setjmp/longjmp 在 C 中实现线程,我记得在大学课堂上这样做过。如果您真的需要它,我会深入研究我的大脑以找出方法。我的第一个想法是你需要分配堆栈空间并调整 jmp_buf,并且为了让它变得更好,你需要一个警报或其他东西(除非你只是想改变正在运行的线程),这将触发一个 longjmp 到下一个正在运行的线程.
-
how can one implement such independent couroutines (which can run when others have died and don't depend on each other)使用 setjmp/longjmp 你不能。你想要的是 preemptive 多任务(或多线程),只有使用某种特权“主管”才能实现。尽管您可以捕获“深层错误”,即某种“C 异常处理”。 -
@user441802,我不确定你的意思,用这种方法实现线程当然是可能的。我认为,协程不仅仅意味着线程。
标签: c++ multithreading coroutine setjmp