gpt4 book ai didi

c - 在c中设置跳转和跳远代码流

转载 作者:太空宇宙 更新时间:2023-11-04 03:20:01 25 4
gpt4 key购买 nike

我正在尝试用 C 语言学习 setjump 和 longjump。任何人都可以帮助我了解以下代码的输出以及代码流和案例的解释。我在代码中调用了函数 funcall()。第一次迭代调用警报,但在后续迭代中未调用警报。为什么会这样? alarm(0) 是否会阻止任何 future 的警报请求?

编辑:即使删除了信号处理程序中的“print_T()”行,代码似乎也没有运行。

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

}

}

最佳答案

由于我的声誉低于 50,因此我无法对除我以外的任何帖子发表评论,以下是您的代码在 mac os 上执行时的输出:

我没有发现您的代码有任何问题 alarm(5)被调用的次数与 funcall() 一样多被称为。

每次调用 funcall() , 先拨alarm(5)设置 SIGALRM 信号在 5 秒后传递给调用进程(它只是正在执行的函数/执行函数的线程),同时代码的其余部分执行。

自从每次调用 funcall()静态变量 p 设置为 0,if(p > 0){...}直到 p 才会执行 block 大于 0,只有当此 block 主体之后的下一条语句 p++ 时才会发生递增 p并使其大于零,被执行。

执行上述if block 并因此调用alarm(0)取决于 for 所花费的时间循环关注 p++终止。如果执行for循环在 5 秒内完成,return 0语句会将控制返回给调用函数。 return将取消所有报警请求并销毁函数调用栈。所以,在这种情况下 alarm(0)不被调用。

接下来,如果执行for循环需要 > 5 秒(忽略所有可能发生的调度延迟,有时可能会导致意外行为),将触发未决警报,从而调用信号处理程序 ti() .当信号处理程序 ti()被调用,调用longjump()setjump() 的调用指令处再次开始执行.当控制到达 alarm(0) 时(假设 for 循环一直执行,直到前面的 if block 没有第二次执行),所有剩余的警报请求都被此调用取消。所以,alarm(0)在 p>0 和 for 之后取消所有未决的警报请求循环时间超过 5 秒。

这里是通过asciinema记录的执行情况 https://asciinema.org/a/fyZX7CRoikq5kLJS2t0Og2rot

这是执行完成后 asciinema session 的屏幕截图。

screen shot of output from asciinema session

关于c - 在c中设置跳转和跳远代码流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47304514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com