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

다음 코드 스 니펫 :

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 초보다 작은 나노초에 의존합니다.



답변

그 이유는 다른 시스템 시계를 (암시 적으로) 사용하기 때문입니다. 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().


답변