2012-06-20 3 views
3

일부 출력을 작성하려면 매 X 초마다 실행해야하는 프로그램이 있습니다. 프로그램은 각 출력 사이에 간헐적 인 폴링 및 처리를 수행합니다. 그래서 예를 들어 5 초마다 결과를 출력 할 수 있습니다.하지만 다음 5 초를 칠 때까지 매 0.1 초마다 폴링을합니다. 이론상의 프로그램은 재시작 사이에 몇 달 동안 실행될 수 있습니다.드리프트에도 불구하고 매 N 초마다 실행하는 Linux/C++ 타이밍 방법?

벽 시계와 일관성을 유지하려면 매 X 초마다 실행해야합니다. 즉, 시계 드리프트가 X 초 표시에서 벗어나도록 허용 할 수 없습니다. 간헐적 인 폴링에서 정확성과 동일한 수준을 필요로하지는 않지만보다 자주 두 번째 폴링을하고 싶습니다. 따라서 초당 순도를 나타낼 수있는 구조체가 필요합니다.

가 나는 OS에서 실행의 본질에 의해 내가 정확히 이제까지 초 X 에서 실행거야 gaurentee 수 없도록 모든 타이머의 실행에 특정 불일치/지연이있을 수 줘야 것을 알고 있습니다. 그러나 그것은 작은 정규 분포를 유지할 때까지 오랫동안 괜찮습니다. 제가 원하지 않는 것은 드리프트가 시간이 계속 더 멀어 지도록 허용하는 것입니다.

가능한 한 폴링의 CPU 비용을 최소화하려고하지만 두 번째 관심사입니다.

필자에게이 수준의 성능을 제공 할 수있는 Linux 용 타이밍 구성 요소는 무엇입니까? 번거로운 배포로 인해 응용 프로그램을 향상시키지 않으려 고하지만, 필요한 경우 사용할 수 있습니다. 그래서 표준 C++ 라이브러리를 사용하는 메소드가 선호됩니다. 그러나 Bosst가 더 잘 할 수 있다면 그것을 알고 싶습니다.

감사합니다.

-ps이므로 C++ 11을 사용할 수 없습니다. 그것은 옵션이 아니므로 어떤 구문을 사용할 수있는 방법이 없습니다.

+0

하드웨어 플랫폼이 무엇입니까? 실시간 커널과 실시간 스케줄링을 계획하고 있습니까? – Chad

+0

또한, "배급에 불편을 겪고있는"것이 무엇입니까? 정적으로 링크하면 배치/배포 할 수 없습니다. – Chad

+0

실시간으로 실행되지 않습니다. 보통의 레드햇 리눅스 (아마). 나는 드리프트를 피하기 위해 실시간의 퍼시션을 필요로하지 않습니다. – dsollen

답변

4

clock_gettimeclock_nanosleep 모두 서브 번째 시간에 동작하며, CLOCK_MONOTONIC의 사용으로 인해 (이러한 NTP 또는 adjtimex 같은) 시스템 시간 조정에 스큐를 방지한다. 예를 들어,

long delay_ns = 250000000; 
struct timespec next; 
clock_gettime(CLOCK_MONOTONIC, &next); 
while (1) { 
    next.ts_nsec += delay_ns; 
    next.ts_sec += ts_nsec/1000000000; 
    next.ts_nsec %= 1000000000; 
    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); 
    /* do something after the wait */ 
} 

현실에서, 당신은 당신이 때문에 신호에 조기 반환했는지 확인해야하고 너무 많은 시간이 당신이 자고있는 동안 전달하기 때문에이 간격을 생략할지 여부를 지정합니다.

다른 수면 방법 (예 : nanosleepselect)은 시간 간격을 지정하고 시스템 시간 인 CLOCK_REALTIME을 사용할 수 있으며 변경 될 수 있습니다.

+2

이것에 따르면 : http://stuff.onse.fi/man?program=clock_gettime§ion=3 CLOCK_MONOTONIC_RAW는 NTP 등으로 인한 시간 변경을 피하기 위해 사용해야하는 것입니다. – Chad

+0

이것은 훌륭한 대답입니다. 하나의 질문을 후속합니다. 나는 실제로 초 단위의 이벤트가있을 때 일찍 인쇄를 허용하여 파일을 읽는 사람들이 계속 볼 수 있도록 할 수 있습니다 (여전히 작업중에 피드백을 얻으려고합니다). 필요한 경우 시계 메서드에 전달하는 데 다른 상수를 사용하여이 작업을 수행 할 수 있다고 가정합니다. – dsollen

0

내가 시작할 때 때 시간을 기록하고 i = (t - t_0)/X (정수 나누기)이 마지막으로 실행 된 동일한 양보다 큰 경우 다시 실행합니다.

예를 들어, 5 초마다 실행한다고 가정하십시오. 23시에 시작한 경우 i = 0, t_0 = 23을 기록하십시오. 그런 다음 27시에 (27 - 23)/5 = 0, 아직 실행하지 마십시오. 하지만 다음 번에는 28 시가되면 (28 - 23)/5 = 1이 0보다 큰 값으로 실행됩니다.

큰 표류를 가질 수있는 틱마다 카운터를 추가하지 않으면 시작할 시간을 절대적으로 계산하므로 정확한 시간을 알 수 있습니다.

+0

더 나은 아직, 다음 실행까지 시간을 계산하고 절전 기능을 사용하십시오. 그러나 열쇠는 현재 시간에서 5 초가 아니라 마지막 시간 이후 5 초를 사용하는 것입니다. –

+0

시간은 단지 1 초의 주술을 가지고 있지만 그렇지 않습니까? 그것은 적어도 1 초의 변동을 허용 할 것입니까? 또한, 내가 할 때마다 시스템 호출을 의미할까요, 아니면 시스템 호출에 대한 필요성을 없애겠습니까? – dsollen

+0

'select'는 초침 잠을줍니다. –

1

지터 또는 시계 드리프트가없는 정확한 타이밍이 필요한 경우 GPS, 원자 시계 또는 라디오 시간 시계와 같은 외부 시간 소스가 있어야합니다. 예를 들어 PDF에 설명 된 NTP 통합을 참조하십시오. 모든 NTP 트릭은 Linux에서 NanoBSD (PDF에 있음)와 마찬가지로 잘 작동합니다.

관련 문제