2017-03-08 10 views
0

나는 sigaction 핸들러가있는 C 프로그램을 작성 중이다. SIGALRM이 잠시 들어오지 않을 경우에 대비하여 itimerval도 있습니다.신호 처리기 인쇄 시간이 경과하는 방법?

핸들러한다

  1. 인쇄 무한 루프의 갯수가
  2. 인쇄 시간
  3. 출구 경과 완료 (1);

신호 처리기가 사용자 정의 매개 변수를 사용하지 않는다는 것을 알아 채었으므로 전역 루프 카운터가 있습니다.
내 문제는 : 어떻게 시간이 경과합니까? 타이머에서 그 정보를 얻습니까? 나는 타이머의 사용법을 완전히 이해하지 못하고있다.
또한 코드는 종료 전 fprintf 호출 후에 루프에서 하나의 여분의 정수를 인쇄합니다. 그것을 고치는 방법?

코드 : 경과 시간을 인쇄하기 위해

#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() 및 friend를 호출하면 안됩니다. 그것은 신호 안전하지 않습니다. – wildplasser

+0

@wildplasser 상기시켜 줘서 고마워,하지만 내 과제가 그렇게하도록 요청한 이후로 전화해야합니다. –

+0

신호 처리기가 종료되면 전체 프로그램이 종료됩니다. 이 작업을 한 번 이상하고 싶다면'exit()'를 호출하지 말고 리턴 할 신호 처리기가 필요합니다. 경과 시간 측정 : 시작 시간을 기록하십시오. 핸들러에서 현재 시간을 찾으십시오. 차이를 계산하고 형식을 지정하십시오. –

답변

0

는, 핸들러는 타이머에 액세스 할 수 있어야합니다. 이를 수행하는 간단한 방법은 타이머를 카운터와 마찬가지로 전역 변수로 사용하는 것입니다. printf() 호출 도중에 신호가 루프를 중단했기 때문에 여분의 정수가 인쇄되는 경우입니다. 루프의 printf()는 제거되어야하며, 총 루프 반복 횟수는 시그널 핸들러에 의해 출력 될 것이다.

+0

루프의 printf()를 제거해야합니까? 아니! 그것은 단순히 프로그램의 목적을 바꾸는 것입니다. 대답하기 전에주의 깊게 고려하십시오. –

+0

내 실수는 파일에서 데이터를 인쇄하는 데 printf()가 필요한 것 같습니다. 이 경우, printf()를 호출하는 동안 핸들러가 메인 루프를 방해하지 못하게 할 수 없습니다. 처리기가 이미 경과 된 시간을 인쇄 한 후에 최종 정수가 인쇄되는 경우가 있습니다. 대안적인 접근법은 핸들러를 부울로 설정하고 부울 값이 변경 될 때 루프가 정상적으로 종료되도록하는 것입니다. 이 경우 경과 된 시간은 주 함수에 의해 루프 이후에 출력되고 마지막으로 종료됩니다. –