首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C中设置跳远和跳远代码

C中设置跳远和跳远代码
EN

Stack Overflow用户
提问于 2017-11-15 10:08:03
回答 1查看 2.3K关注 0票数 1

我试着在C中学习for跳远和跳远,有人能帮我完成以下代码的输出、代码流以及对这些情况的解释吗?我在代码中调用了一个函数funcall()。警报在第一次迭代中被调用,但是在随后的迭代中,警报没有被调用。为什么会这样呢?警报(0)是否阻止任何未来的警报请求?

编辑:即使在删除信号处理程序中的"print_T()“行之后,代码似乎也不会运行。

代码语言:javascript
复制
#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;
           }

    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-15 11:25:07

由于我的名誉不足50,所以除了我的帖子之外,我不能对任何帖子发表评论,所以下面是在mac os上执行代码时的输出:

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

对于每个对funcall()的调用,第一次对alarm(5)的调用设置了SIGALRM信号,以便在代码的其余部分执行时,在5秒后传递给调用进程(这只不过是正在执行/线程执行函数的函数)。

由于每次对funcall()静态变量p的调用都设置为0,所以在p大于0之前不会执行if(p > 0){...}块,只有在执行该块主体后面的下一条语句,即p++递增p并使其大于零时才会执行。

执行前面提到的if块并因此调用alarm(0)取决于for循环在p++之后终止所花费的时间。如果for循环的执行在5秒内完成,return 0语句将将控件返回给调用函数。return将取消所有报警请求,并销毁函数调用堆栈。因此,在这种情况下,不调用alarm(0)

接下来,如果for循环的执行时间超过5秒(忽略可能发生并有时可能导致意外行为的所有调度延迟),则将触发挂起的警报,从而调用信号处理程序ti()。当调用信号处理程序ti()时,对longjump()的调用将在setjump()的调用指令处再次启动。当控制到达alarm(0)时(假设for循环继续执行,只要前面的if块第二次没有被执行),所有剩余的警报请求都会被这个调用取消。因此,alarm(0)会在p>0和for循环超过5秒后取消所有挂起的警报请求。

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

这里是执行完成后asciinema会话的屏幕截图。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47304514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档