C 코드에서 timespec_get ()의 초 구성 요소보다 1 초 뒤에 time ()으로 시간이보고되는 이유는 무엇입니까?


12

다음 코드 스 니펫 :

struct timespec ts;
for (int x = 0; x < 100000000; x++) {
    timespec_get(&ts, TIME_UTC);
    long cTime = (long) time(NULL);
    if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) {
        printf("cTime: %ld\n", cTime);
        printf("ts.tv_sec: %ld\n", ts.tv_sec);
        printf("ts.tv_nsec: %ld\n", ts.tv_nsec);
    }
}

이 출력을 생성합니다.

...
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2527419
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2534036
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2540359
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2547039
...

왜 사이의 차이 cTimets.tv_sec? 조건이로 변경되면 문제가 발생하지 않습니다 ts.tv_nsec >= 3000000. 이 문제는 3 초보다 작은 나노초에 의존합니다.


사용 된 운영 체제, 버전, 사용 된 C 라이브러리 버전에 대해 더 구체적이어야합니다.
일부 프로그래머 친구

2
@Someprogrammerdude Linux 데비안 8, GCC 6.3.0.
Theo d' Or

무엇입니까 timespec_get()? 이 C 또는 C ++입니까? 처럼 보입니다 std::timespec_get. 적절한 태그를 사용하십시오.
마르코 보 넬리

@MarcoBonelli : C11에서 C에 추가되었습니다. 온라인으로 재생할 수 있습니다 .
ShadowRanger

@ShadowRanger 참조 해 주셔서 감사합니다. 시스템에 대한 man항목을 볼 수 없으므로 timespec_get결론에 도달했습니다. 맞는 말이다.
마르코 보 넬리

답변:


11

그 이유는 다른 시스템 시계를 (암시 적으로) 사용하기 때문입니다. timespec_get()용도 고해상도 동안, 시스템 전체의 실시간 클럭을 time()사용하는 거친 실시간 시계.

사용하려고

clock_gettime(CLOCK_REALTIME_COARSE, &ts);

대신에 timespec_get()차이점이 사라집니다.

편집하다:

이것은 Linux 커널 소스 vclock_gettime.c 에서 볼 수 있습니다.

실제로이 문제는 여기서보기에 약간 미묘합니다. 구조 부재의 초 부분에 의해 사용 CLOCK_REALTIME_COARSECLOCK_REALTIME동일한 값을 포함하지만, 나노초 부분은 상이하다; 와 CLOCK_REALTIME그것보다 클 수있다 1000000000(이는 1 초). 이 경우 통화가 고정됩니다.

ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;

이 수정은 CLOCK_REALTIME_COARSE또는로 수행 되지 않습니다 time(). 이 차이에 대해 설명 CLOCK_REALTIME하고를 time().


이것은 어디에서나 문서화되어 있습니까 time(아마도) 더 성능이 뛰어나지 만 덜 정확한 시계로 구현되고 있습니까 (어쨌든 정밀도가 필요한 사람은 두 번째 입도 만 있다는 이론에서)? 두 번째 세분성 만 요구할 때 밀리 초 정도의 실시간 지연 (온라인 테스트는 때때로 ms 이상 지연이 발생했지만 그다지 크지 않음)은 중요하지 않습니다.
ShadowRanger

@ShadowRanger 더 자세한 내용을 추가했습니다
Ctx

의도를 명시 적으로 문서화하지는 않았지만, 투표 용으로 충분합니다. :-) 시계가 실제로 1 초 이상의 추가 나노초 이상을보고 할 수 있다는 것이 재미 있습니다.
ShadowRanger

@ShadowRanger 나는 그 출처 이외의 실제 문서를 찾을 수 없었습니다. 이는 또한 사전 통지없이 행동이 세부적으로 변경 될 수 있음을 의미합니다
Ctx

@Ctx 자세한 답변 감사합니다! timespec_get ()이 POSIX가 아닌 C11이므로 사용할 시계 설정이 필요하지 않으므로 clock_gettime () 대신 timespec_get ()을 사용합니다. 나는 다른 시계가 사용되었다는 것을 몰랐지만 선택이 주어지면 거친 시계를 사용하는 데 많은 포인트가 보이지 않습니다.
Theo d' Or
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.