2017-03-08 55 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()期間中斷主循環。這有時會導致在處理程序已經打印完逝去的時間之後打印出最終的整數。另一種方法是將處理程序設置爲布爾值,並在布爾值發生更改時使循環正常退出。在這種情況下,經過的時間將被主函數打印,在循環之後,最終退出之前。 –