2014-02-22 51 views
0
#include <features.h> 
#include <time.h> 
#include <sys/time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

#include <netinet/in.h> 
#include <arpa/inet.h> 

typedef unsigned int uint32; 

#define million 1000000L 

long duration2ms, duration10ms, duration100ms; 
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster; 
timer_t firstTimerID, secondTimerID, thirdTimerID; 

void TASK1(Task2ms_Raster) { 
    struct timespec start, stop; 
    int a, b, c; 
    uint32 StartTime, StopTime; 
    a=1, b=2, c=3; 

    if((StartTime = clock_gettime(CLOCK_REALTIME, &start)) == -1) { 
     perror("clock gettime"); 
    } 


     a= b+c; 
     b = c+a; 
     c= a+b; 

     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; a= b+c; 
     b = c+a; 
     c= a+b; 

//我做過幾次這樣的事情。如何解決linux定時器錯誤?

printf("ETAS\n"); 
    printf("ETAS1\n"); 
    if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1) { 
     perror("clock gettime"); 
    } 
    duration2ms = (stop.tv_sec - start.tv_sec) + 
        (double)(stop.tv_nsec - start.tv_nsec)/
        (double)million; 
    printf("time difference is= %ld\n", duration2ms); 
} 

void TASK2(Task10ms_Raster) { 
    struct timespec start, stop; 
    if(clock_gettime(CLOCK_REALTIME, &start) == -1) { 
     perror("clock gettime"); 
    } 
    printf("ETAS2\n"); 
    printf("ETAS3\n"); 
    if(clock_gettime(CLOCK_REALTIME, &stop) == -1) { 
     perror("clock gettime"); 
    } 
    duration10ms = (stop.tv_sec - start.tv_sec) + 
        (double)(stop.tv_nsec - start.tv_nsec)/
        (double)million; 
    printf("time difference is= %ld\n", duration10ms); 
} 

void TASK3(Task100ms_Raster) { 
    struct timespec start, stop; 
    if(clock_gettime(CLOCK_REALTIME, &start) == -1) { 
     perror("clock gettime"); 
    } 
    printf("ETAS4\n"); 
    printf("ETAS5\n"); 
    if((clock_gettime(CLOCK_REALTIME, &stop)) == -1) { 
     perror("clock gettime"); 
    } 
    duration100ms = (stop.tv_sec - start.tv_sec) + 
        (double)(stop.tv_nsec - start.tv_nsec)/
        (double)million; 
    printf("time difference is= %ld\n", duration100ms); 
} 

static void timerHandler(int sig, siginfo_t *si, void *uc) { 
    timer_t *tidp; 
    tidp = si->si_value.sival_ptr; 
    if (*tidp == firstTimerID) 
     TASK1(Task2ms_Raster); 
    else if(*tidp == secondTimerID) 
     TASK2(Task10ms_Raster); 
    else if(*tidp == thirdTimerID) 
     TASK3(Task100ms_Raster); 
} 

static int makeTimer(char *name, 
        timer_t *timerID, 
        int expireMS, 
        int intervalMS) { 

    struct sigevent   te; 
    struct itimerspec  its; 
    struct sigaction  sa; 
    int      sigNo = SIGRTMIN; 

    /* Set up signal handler. */ 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = timerHandler; 
    sigemptyset(&sa.sa_mask); 
    if(sigaction(sigNo, &sa, NULL) == -1) { 
     perror("sigaction"); 
    } 

    /* Set and enable alarm */ 
    te.sigev_notify = SIGEV_SIGNAL; 
    te.sigev_signo = sigNo; 
    te.sigev_value.sival_ptr = timerID; 
    timer_create(CLOCK_REALTIME, &te, timerID); 

    its.it_interval.tv_sec = 0; 
    its.it_interval.tv_nsec = intervalMS * 1000000; 
    its.it_value.tv_sec = 0; 
    its.it_value.tv_nsec = expireMS * 1000000; 
    timer_settime(*timerID, 0, &its, NULL); 

    return 1; 
} 

int main(void) { 
    makeTimer("First Timer", &firstTimerID, 2, 2); //2ms 
    makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms 
    makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms 
    while(1) { 
     sleep(100); 
    } 
} 

我創建了一個計時器,每2ms,10ms和100ms調用一次任務。這些任務只是打印該值並計算打印該值的開始時間和停止時間。當我運行上述程序時,它不顯示開始時間和停止時間之間的時間差(即持續時間2ms,持續時間10ms和持續時間100ms)。有人可以幫助我嗎?

+1

將其發佈到世界時請格式化您的代碼。 – alk

+0

我還建議您儘可能簡短並儘量使用您的代碼示例。現在,您只需粘貼不需要的複雜代碼即可,不會指出您遇到的問題。 –

+0

爲什麼它不顯示開始時間和停止時間之間的差異? – user3340661

回答

1

在所有情況下,時差都將顯示爲零,因爲您正在測量打印兩行非常快的時間。你是而不是計時每個任務的調用之間的時間。

如果您想測量任務調用之間的時間,則需要保留時間。舉例來說,我將展示一項任務:

void TASK3(Task100ms_Raster) { 
    static struct timespec start, stop = { .tv_sec = -1 }; // static duration! 
    if (stop.tv_sec < 0) { 
     (void) clock_gettime(CLOCK_REALTIME, &stop); // first time run 
    } 
    start = stop; // start from previous stop time 

    // do whatever here 

    (void) clock_gettime(CLOCK_REALTIME, &stop); 

    duration100ms = (stop.tv_sec - start.tv_sec) 
        + (double)(stop.tv_nsec - start.tv_nsec) 
        /(double)million; 
    printf("time difference is= %ld\n", duration100ms); 
} 
+0

你在哪裏計算開始時間? – user3340661

+0

@ user3340661'start = stop'其中'stop'是前一個停止時間(或第一次運行的當前時間)。 (請注意'靜態'持續時間與您的代碼不同。) – Arkku

+0

謝謝!但爲什麼你要指定靜態持續時間?我不明白 !!你在什麼基礎上指定它爲-1(.tv_sec = -1) – user3340661

0

問題是,您不會將任何時間值保存在TASK *()中的任何位置。這意味着clock_gettime()會連續被調用兩次,中間幾乎沒有時間。你應該做的是沿着以下線的東西:

#include <features.h> 
#include <time.h> 
#include <sys/time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

#include <netinet/in.h> 
#include <arpa/inet.h> 

typedef unsigned int uint32; 
timer_t tmr; 
struct timespec prev; 

static void handle_timer(int sig, siginfo_t *si, void *uc) { 
    timer_t *tidp; 
    struct timespec current; 

    tidp = si->si_value.sival_ptr; 
    clock_gettime(CLOCK_REALTIME, &current); 
    printf("dif between calls to handle_timer: %ld\n", 
    current.tv_sec - prev.tv_sec); 
    prev = current; 
} 

int main(int argc, char **argv) { 
    struct sigevent se; 
    struct itimerspec  its; 
    struct sigaction  sa; 
    clock_gettime(CLOCK_REALTIME, &prev); 

    /* Set up signal handler. */ 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = handle_timer; 
    sigemptyset(&sa.sa_mask); 
    if (sigaction(SIGRTMIN, &sa, NULL) == -1) 
    perror("sigaction"); 

    /* Set and enable alarm */ 
    se.sigev_notify = SIGEV_SIGNAL; 
    se.sigev_signo = SIGRTMIN; 
    se.sigev_value.sival_ptr = &tmr; 
    timer_create(CLOCK_REALTIME, &se, &tmr); 

    its.it_interval.tv_sec = 1; 
    its.it_value.tv_sec = 1; 
    its.it_value.tv_nsec = 0; 
    timer_settime(&tmr, 0, &its, NULL); 

    while(1) 
    sleep(100); 
    return 0; 
} 

這裏的區別是,我們實際上節省了時間handle_time()被調用,然後計算對保存的時間差。

+0

我想計算在函數內開始執行時所花費的時間。不想計算從調用特定任務的時間。 – user3340661