在c中设置跳跃和跳远码流
我正在尝试学习C语言中的setjump和longjump。有谁能帮助我输出以下代码以及代码流和案例解释。我在代码中调用了函数funcall()。在第一次迭代中调用报警,但在随后的迭代中不调用报警。为什么会这样?报警(0)是否阻止任何未来的报警请求 编辑:即使删除信号处理程序中的“print_T()”行,代码似乎也不会运行在c中设置跳跃和跳远码流,c,setjmp,C,Setjmp,我正在尝试学习C语言中的setjump和longjump。有谁能帮助我输出以下代码以及代码流和案例解释。我在代码中调用了函数funcall()。在第一次迭代中调用报警,但在随后的迭代中不调用报警。为什么会这样?报警(0)是否阻止任何未来的报警请求 编辑:即使删除信号处理程序中的“print_T()”行,代码似乎也不会运行 #include <stdio.h> #include <setjmp.h> #include <signal.h> #include &l
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <time.h>
#define LEN 50
jmp_buf po;
void print_T() {
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime ( &rawtime );
printf ( "Current local time and date: %s", asctime (timeinfo) );
}
static void ti() {
print_T();
longjmp(po,1);
}
int funcall(int reply) {
static int p;
p = 0;
signal(SIGALRM, ti);
int q = setjmp(po);
if(q == 0)
printf("the value BEFORE setjmp %d for reply %d\n", p, reply);
else
printf("the value AFTER setjmp %d for reply %d\n", p, reply);
alarm(5);
if(p > 0) {
printf("INVOKING THE ALARM");
alarm(0);
return -1;
}
p++;
for(int i = 0; i < 100000; i++)
for(int j = 0; j < 100000; j++);
return 0;
}
int main() {
int a;
int reply;
time_t start, end;
for(reply=0; ; reply++) {
printf("~~~~~~~~~~~~~~~~~~~~~~~~~ITERATION NUMBER %d\n", reply);
time(&start);
a = funcall(reply);
time(&end);
double tin = difftime(end, start);
printf("*********************ITERATION END and a returned is %d after %f\n", a, tin );
double tidiff = difftime(end, start);
if(a < 0)
if(reply == 10) {
break;
}
}
}
#包括
#包括
#包括
#包括
#定义LEN 50
jmp_buf po;
无效打印(){
时间与时间;
结构tm*时间信息;
时间(&rawtime);
timeinfo=localtime(&rawtime);
printf(“当前本地时间和日期:%s”,asctime(timeinfo));
}
静态孔隙ti(){
print_T();
longjmp(po,1);
}
int funcall(int回复){
静态int-p;
p=0;
信号(SIGALRM,ti);
int q=setjmp(po);
如果(q==0)
printf(“设置jmp%d之前的值,用于回复%d\n”,p,reply);
其他的
printf(“setjmp%d之后的值,用于回复%d\n”,p,reply);
警报(5);
如果(p>0){
printf(“调用警报”);
报警(0);
返回-1;
}
p++;
对于(int i=0;i<100000;i++)
对于(int j=0;j<100000;j++);
返回0;
}
int main(){
INTA;
int回复;
开始、结束的时间;
for(reply=0;reply++){
printf(“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~迭代编号%d\n”,答复);
时间(&开始);
a=funcall(回复);
时间(&结束);
双锡=扩散时间(结束、开始);
printf(“*********************迭代结束,返回的是%f\n”后的%d”,a,tin);
双TIDIF=difftime(结束,开始);
if(a<0)
if(回复==10){
打破
}
}
}
由于我的声誉不到50,因此除了我的帖子之外,我无法对其他帖子发表评论,因此,以下是在mac os上执行代码时的输出:
我认为您的代码没有任何问题,因为调用报警(5)
的次数与调用funcall()
的次数相同
对于每次调用funcall()
,第一次调用alarm(5)
将设置SIGALRM信号,该信号将在5秒后发送到调用进程(这只是正在执行的函数/线程执行该函数),而代码的其余部分将执行
由于在对funcall()
静态变量p的每次调用中设置为0,if(p>0){…}
块将不会执行,直到p
大于0,只有当该块体后面的下一条语句p++
递增p
并使其大于0时才会执行该块,被执行
上述if块的执行,因此调用报警(0)
取决于循环在p++
之后终止所用的时间。如果for
循环的执行在5秒内完成,return 0
语句将把控件返回给调用函数。返回将取消所有报警请求并销毁函数调用堆栈。因此,在这种情况下,不会调用报警(0)
接下来,如果执行for
循环需要>5秒(忽略所有可能发生并有时可能导致意外行为的调度延迟),将触发挂起的警报,从而调用信号处理程序ti()
。当调用信号处理程序ti()
时,将调用longjump()
,并在setjump()
的调用指令处再次开始执行。当控件到达报警(0)
时(假设for
循环的持续执行时间与前面的相同,如果第二次未执行块),则此调用将取消所有剩余的报警请求。因此,alarm(0)
会在p>0之后取消所有挂起的报警请求,而for
循环所需时间超过5秒
以下是通过asciinema记录的执行情况
下面是执行完成后asciinema会话的屏幕截图
我建议您先阅读,例如。您所做的可能是个坏主意。@有些程序员在这里有很多“坏主意”,比如从信号处理程序调用非异步安全函数。@EOF请详细说明。这是我第一次使用setjmp和longjmpApart,因为它们的想法不好,在ubuntu16.04linuxintq=setjmp(po)上似乎确实“起作用”
您不能从setjump分配(甚至更糟:将其用作初始值设定项表达式)“返回值”,您只能对其进行测试。