2010-03-10 3 views
3

1 분 간격으로 파일을 생성하는 작은 프로그램을 작성했습니다. 그러나 파일이 작성되고 마지막으로 작성된 시간과 ls 명령에 표시된 파일의 최종 수정 시간은 1 초 차이가납니다. 코드와 출력은 아래에 나와 있습니다. 버그가 어디 있는지 알려주세요. 파일에Linux time() 함수 또는 Linux OS 호출의 버그입니까?

[email protected]:/home/srinivas# cat b.c 
#include <time.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <fcntl.h> 
int main() 
{ 
    int fd; 
    int i=0; 
    time_t initial_time = time(NULL); 
    time_t interval = 60; 
    time_t curr_time = time(NULL); 

    fd=open ("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); 
    write(fd,"abcd1",5); 
    while(1) 
    { 
     curr_time = time(NULL); 
     if(curr_time >= initial_time) 
     { 
      if(i==0) 
      { 
       close(fd); 
       printf("\ntime before test2.txt fileopen= %d\n", time(NULL)); 
       fd=open ("test2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); 
       write(fd,"abcd2",5); 
       printf("time after test2.txt filewrite= %d\n", time(NULL)); 
       system("ls -l --time-style=+%s test2.txt"); 
       initial_time += interval; 
       i=1; 
      } 
      else 
      { 
       close(fd); 
       printf("\ntime before test1.txt fileopen= %d\n", time(NULL)); 
       fd=open ("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); 
       write(fd,"abcd1",5); 
       printf("time after test1.txt filewrite= %d\n", time(NULL)); 
       system("ls -l --time-style=+%s test1.txt"); 
       initial_time += interval; 
       i=0; 
      } 
     } 
     usleep(1000); 
    } 
    return 0; 
} 
[email protected]:/home/srinivas# gcc b.c 
[email protected]:/home/srinivas# ./a.out 

time before test2.txt fileopen= 1268203133 
time after test2.txt filewrite= 1268203133 
-rw-r--r-- 1 root root 5 1268203133 test2.txt 

time before test1.txt fileopen= 1268203193 
time after test1.txt filewrite= 1268203193 
-rw-r--r-- 1 root root 5 1268203192 test1.txt 

time before test2.txt fileopen= 1268203253 
time after test2.txt filewrite= 1268203253 
-rw-r--r-- 1 root root 5 1268203252 test2.txt 

time before test1.txt fileopen= 1268203313 
time after test1.txt filewrite= 1268203313 
-rw-r--r-- 1 root root 5 1268203312 test1.txt 

time before test2.txt fileopen= 1268203373 
time after test2.txt filewrite= 1268203373 
-rw-r--r-- 1 root root 5 1268203372 test2.txt 

[email protected]:/home/srinivas# ls -ltr --time-style=+%s 
total 40 
-rwxrwxrwx 1 root  root  1095 1268202457 b.c 
-rwxr-xr-x 1 root  root  10300 1268202459 a.out 
-rw-r--r-- 1 root  root   5 1268203312 test1.txt 
-rw-r--r-- 1 root  root   5 1268203372 test2.txt 
[email protected]:/home/srinivas# 

감사와 관련,

스 리니 바스

+0

그것은 여기 잘 작동하지만 당신이보고있는 것은 ... 홈 디렉토리 아마도 NFS, 또는 특별한 마운트 옵션과 같은 몇 가지 "이상한"파일 시스템을 사용하고 정말 예상치 못한입니까? – Martin

+0

@Martin - 로컬로 마운트 된 파일 시스템에서 이것을 재현 할 수 있습니다. 매우 이상합니다. –

+0

@Martin - My/home은 ext3 형식입니다. 마운트 된 파티션이 아닙니다. –

답변

-1
  • 쓰기는 약간의 시간이 소요됩니다.
  • time() 함수를 호출하는 데 약간의 시간이 걸립니다.
  • time() 함수의 논리 연산이 약간의 시간이 걸립니다. 1 초 지연

이 모든 결과는 모든 버그에 있지 ..Its!

2

먼저, 코드에 문제가 있습니다.

  • 루프 전에 open()write()을 제거하면 아무것도 수행하지 않습니다.
  • close() 전화를 write() 전화 바로 다음으로 이동하십시오.

이렇게하면 ls를 사용하여 수정 시간을 확인하기 전에 데이터를 쓰고 파일을 닫을 수 있습니다. 그렇지 않으면 write()와 close() 사이에 1 초의 지연이 있습니다. 5 바이트 만 쓰기 때문에 버퍼링됩니다. 따라서 write() 호출 후 시간을 확인할 때 데이터가 아직 쓰여지지 않았다는 보장이 없으므로 파일이 수정되지 않았을 수 있으며 이로 인해 결과가 엉망이 될 수 있습니다.

둘째, time()ls이 1 초의 차이를보고하기 때문에 1 초 지연을 가정 할 수 없습니다. 초 단위가 가장 작은 단위이기 때문에 반올림 차이를 기대해야합니다. 그리고 Epoch 이후로 초를 가져 오는 데는 두 가지 다른 방법을 사용하기 때문에 서로 다른 반올림 규칙을 사용하기 때문에 쉽게 1 초의 차이가 발생할 수 있습니다. 수정 시간을 저장하는 파일 시스템을 추가하면 실제로 결과에 영향을 미칠 수있는 세 가지 액터가 있습니다.

또한 결과를 올바르게 보면 이 ls보다 1 초 늦다는 것을 알 수 있습니다. 그래서, 당신은 전혀 지체하지 않습니다, 당신은 제 시간에 돌아갈 것입니다! 반올림 차이가 가장 큰 이유입니다.

Linux time() 함수 또는 Linux OS 호출에는 버그가 없습니다.

+0

사실 이것은 정확히 원래 필요한 프로그램/기능의 복제본입니다. 따라서 open(), write() 함수를 사용하여 문제를 숨길 수는 있지만 원래 코드 때문에 공개 된 문제에 대한 해결책을 찾고있었습니다. –

+0

@Srinivas 당신의 말을 잘 모르겠습니다. 당신이 open()하고 write()하는 것을 원하지 않습니다. 이렇게하면 write() 호출 후에 close() 호출을 할 수 있으므로 지연 시간이 없습니다. 그렇지 않으면 write()와 close() 사이에 1 초의 지연이 있습니다. 5 바이트 만 쓰기 때문에 버퍼링됩니다. 따라서 write() 호출 후 시간을 확인할 때 데이터가 기록되었다고 보장 할 수 없으므로 파일이 수정되지 않았을 수 있으므로 결과가 엉망이 될 수 있습니다. –