2017-03-08 52 views
0

我正在编写一个具有sigaction处理程序的C程序。如果SIGALRM不在一段时间,它也有一个itimerval。如何让信号处理程序的打印时间过去?

处理程序应该

  1. 打印无限循环的总数完成
  2. 打印所经过的时间
  3. 出口(1);

我注意到,信号处理程序不带自定义参数,所以我有一个全局环计数器。
我的问题是:如何获得时间流逝?我能从计时器获得这些信息吗?我不完全了解定时器的用法。
另外,代码在终止之前在fprintf调用之后打印1个额外的整数(来自循环)。如何解决这个问题?

代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <signal.h> 
#include <unistd.h> 
#include <sys/time.h> 

int count = 0; 

void handler (int code) { 
    fprintf(stderr, "Reads completed: %d \n", count); 
    exit(1); 
} 

int main(int argc, char const *argv[]) 
{ 
    if (argc != 3) { 
     fprintf(stderr, "Usage: time_reads FILENAME TIMER\n"); 
     exit(1); 
    } 

    FILE *fp; 
    fp = fopen(argv[1], "rb"); 
    if (fp == NULL) { 
     fprintf(stderr, "Fail to open file\n"); 
     exit(1); 
    } 

    int i; 
    srand(time(NULL)); 

    struct sigaction sa; 
    sa.sa_handler = handler; 
    sa.sa_flags = 0; 
    sigemptyset(&sa.sa_mask); 
    sigaction(SIGALRM, &sa, NULL); 

    struct itimerval timer; 
    timer.it_value.tv_sec = strtol(argv[2], NULL, 10 ); 
    timer.it_value.tv_usec = 0; 
    timer.it_interval.tv_sec = 0; 
    timer.it_interval.tv_usec = 0; 

    if (setitimer(0, &timer, NULL) < 0) { 
     fprintf(stderr, "Fail to set timer\n"); 
     exit(1);  
    } 

    while(1) { 
     fseek(fp, (rand() % 100) * sizeof(int), SEEK_SET); 
     fread(&i, sizeof(int), 1, fp); 
     printf("%d\n", i); 
     count++; 
    } 

    fclose(fp); 

    return 0; 
} 
+0

注意:您不应该从信号处理程序调用printf()(和朋友)。这不是信号安全的。 – wildplasser

+0

@wildplasser感谢提醒,但我必须打电话给我,因为我的任务要求这样做。 –

+0

请注意,如果信号处理程序退出,则整个程序将退出。如果你想多次执行此操作,则需要返回信号处理程序,而不是调用'exit()'。至于测量所用时间:记录开始时间;在处理程序中,查找当前时间;计算并格式化差异。 –

回答

0

为了打印所经过的时间,处理程序必须能够访问定时器。一个简单的方法就是让计时器也是一个全局变量,就像计数器一样。对于正在打印的额外整数,这是因为在调用printf()的过程中,信号中断了循环。循环中的printf()应该被删除,因为循环迭代的总数将由信号处理程序打印。

+0

循环中的printf()应该被删除?没有!这只是简单地改变程序的目的。在回答之前请仔细考虑。 –

+0

我的错误,看起来像打印文件中的数据需要printf()。在这种情况下,无法阻止处理程序在调用printf()期间中断主循环。这有时会导致在处理程序已经打印完逝去的时间之后打印出最终的整数。另一种方法是将处理程序设置为布尔值,并在布尔值发生更改时使循环正常退出。在这种情况下,经过的时间将被主函数打印,在循环之后,最终退出之前。 –