2012-05-13 1 views
0

다음 예제 코드를 사용할 때 tv_nsec 값은 이고 long이기 때문에 반복 루핑하는 것으로 가정합니다.C++는 clock_gettime() 오버플로입니까?

#include <iostream> 
using namespace std; 
#include <time.h> 

int main(int argc, char *argv[]) { 
    timespec time1, time2; 
    timespec timens = {0}; 
    timens.tv_sec = 1; 

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 
    nanosleep(&timens, (struct timespec *)NULL); 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 

    cout << time1.tv_nsec << " : " << time2.tv_nsec << endl; 
    cout << (time2.tv_nsec-time1.tv_nsec) << endl; 
    return 0; 
} 

$ ./microtime 
2754095 : 2766801 
12706 

시작 시간과 종료 시간 사이의 차이가 12706ns (12.7us가)가 1 초 동안 잠을 12us을하지 않았다, 나는 합리적으로 그 확신 해요! 그래서 여기서 일어난 일은 tv_nsec이 돌았습니까? unsigned long (0 ~ 4294967295) 대신 양수 값 (0 ~ 2147483647)의 작은 범위를 지정하는 것이 singed long이라고 가정하면 2147483647 나노 초는 여전히 2 초 이상입니다.

코드를 다음과 같이 변경하면 여전히 잘못된 출력이 표시 될 수 있습니다.

timens.tv_sec = 0; 
timens.tv_nsec = 100000; 

$ ./microtime 
2743552 : 2754327 
10775 

수면 지속 시간은 100,000ns로 설정되었지만 출력에 따르면 프로그램은 10,000ns 동안 잠자기 상태입니다. 그게 시간의 작은 금액을 알아하지만 여기에 하나의 초 또는 100us와 같은 짧은 시간이든, 여기에 정확성이나 이러한 값 사이에 아무 것도없는 것 여부를 보여 주려고 노력하고있어. 내가 잘못한 일을하고 있습니까? 어떻게 잘못했는지 구현 했습니까? clock_gettime()을 호출하는 사이에 실제 이벤트 지속 시간을 가져올 수없는 이유는 무엇입니까?

시간을 내 주셔서 감사합니다.

업데이트

@Oli; 나는 다음과 같은 코드를 사용하여 제안을 테스트 할 수 있지만 작동하지 않는 것 :

int main(int argc, char *argv[]) { 
    timespec time1, time2; 
    timespec timens = {0}; 
    timens.tv_sec = 1; 
    timens.tv_nsec = 0; 

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 
    nanosleep(&timens, (struct timespec *)NULL); 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 

    cout <<time1.tv_sec<<"s:"<<time1.tv_nsec<<"ns : "<< 
     time2.tv_sec<<"s:"<<time2.tv_nsec<<"ns"<<endl; 
    cout <<(time2.tv_nsec-time1.tv_nsec)<<endl; 
    return 0; 
} 

$ ./microtime 
0s:2801478ns : 0s:2813732ns 
12254 

답변

4

은 또한 시간 간격을 계산할 때 계정에 tv_sec 필드를 취할 필요가있다.

UPDATE

또한,이 공정에 사용 CLOCK_PROCESS_CPUTIME_ID 대책 CPU 시간. nanosleep으로 양보하면이 타이머가 증가하지 않습니다. 예를 들어보십시오. CLOCK_MONOTONIC 대신 nano_sleep의 설명서에서

+0

Ah! 그래서 첫 번째 예에서는 tv_sec가 1로 증가하고 tv_nsec이 나머지를 유지할 것이라고 말하고 있습니까? – jwbensley

+0

@ javano : 예, 정확하게. –

+0

완벽하게 이해할 수는 있지만 작동하지 않는 것 같습니다 (나는 질문을 업데이트했습니다). 원래의 테스트와이 새로운 테스트에서 시작 시간과 종료 시간의 차이는 매번 10k ~ 12k 나노초 사이라는 것을 볼 수 있습니다. 이렇게 느린 테스트는 매번 다른 테스트를 할 때마다 작은 창이됩니다. 우연히 더 많은 것이 올바르게 작동하지 않습니다. – jwbensley

2

:

마스킹되지 않은 신호는 인터럽트 신호에 관계없이 SA_RESTART 값, 초기 슬립을 정지 인 nanosleep()를 일으킬 것이다. 인 nanosleep()의

결과

에게 당신의 사용법은 단순하다 : 그것은 (이 시험은 아니지만 당신에게 거친 아이디어를 제공하기 위해) 같이한다
.

timespec requestedSleep = {0}; 
requestedSleep.tv_sec = 1; 

timespec start = {0}; 
start = /* current real time */; 

while(nanosleep(&requestedSleep, NULL) == -1) 
{ 
    timespec end.t = {0}; 
    end = /* current real time */; 

    updateRequestedSleepTime(requestedSleep, start, end); 
    start = end; 
} 
+0

nanosleep에 대한이 추가 정보를 주셔서 감사합니다 Loki, 나는 테스터 애플 리케이션이 물건을 채우고 놀 것입니다. 고마워요 : D – jwbensley