2016-12-10 195 views
4

所以我必須解決這個鍛鍊情況不同。編寫一個程序,最多需要三個命令行參數:寫()在兩種情況下

$ atomic_append filename num-bytes [x] 

這個文件應該打開指定的文件名(如果有必要創建它),並通過使用write()一次寫一個字節追加num-bytes字節的文件。默認情況下,程序應使用O_APPEND標誌打開文件,但如果提供了第三個命令行參數(x),則應該省略O_APPEND標誌,而應在每個write()之前執行lseek(fd, 0, SEEK_END)調用。在同一時間運行該程序的兩個實例,而不x參數寫入1個百萬字節到同一個文件:

$ atomic_append f1 1000000 & atomic_append f1 1000000 

重複相同的步驟,寫入不同的文件,但是這次指定x參數:

$ atomic_append f2 1000000 x & atomic_append f2 1000000 x 

使用ls –l列出文件f1和f2的大小並解釋差異。

所以這是我寫的:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 

int main(int argc, char *argv[]) { 
     int fd, flags, num_bytes; 
     if (argc < 3 || strcmp(argv[1], "--help") == 0) { 
       printf("Usage: %s filename num-bytes [x]\n", argv[0]); 
       return 1; 
     } 
     num_bytes = atoi(argv[2]); 
     if (argc == 4 && strcmp(argv[3], "x") == 0) { 
       fd = open(argv[1], O_CREAT | O_WRONLY, 0666); 
       if (fd == -1) 
         perror("open"); 
       while (num_bytes-- > 0) { 
         lseek(fd, 0, SEEK_END); 
         write(fd, "a", 1); 
       } 
       if (close(fd) == -1) 
         perror("close"); 
     } 
     else { 
       fd = open(argv[1], O_CREAT | O_APPEND | O_WRONLY, 0666); 
       if (fd == -1) 
         perror("open"); 
       while(num_bytes-- > 0) 
         write(fd, "a", 1); 
       if (close(fd) == -1) 
         perror("close"); 
     } 
     return 0; 
} 

現在後我跑了它的要求:

[email protected]:~/System/5$ ./a.out f1 1000000 & ./a.out f1 1000000 
[1] 4335 
[1]+ Done     ./a.out f1 1000000 
[email protected]:~/System/5$ ./a.out f2 1000000 x & ./a.out f2 1000000 x 
[1] 4352 
[1]+ Done     ./a.out f2 1000000 x 
[email protected]:~/System/5$ ls f1 f2 
f1 f2 
[email protected]:~/System/5$ ls -l f* 
-rw-rw-r-- 1 abhinav abhinav 2000000 Dec 10 16:23 f1 
-rw-rw-r-- 1 abhinav abhinav 1000593 Dec 10 16:24 f2 

肯定地說,有文件大小的差異我有些無法清楚地瞭解爲什麼?我搜索,發現某處這樣的解釋:

尺寸有絕對不同:

-rw------- 1 posborne posborne 1272426 2012-01-15 21:31 test2.txt 
-rw------- 1 posborne posborne 2000000 2012-01-15 21:29 test.txt 

哪裏的test2.txt未經O_APPEND運行。 test2.txt由 短於 文件末尾的 末尾沒有發生與寫入同時發生(相當於 頻繁)的次數(或字節由於次數)。

但它似乎沒有任何意義。那麼爲什麼尺寸的差異呢?

回答

1

此代碼,在不與O_APPEND打開的文件運行:

  while (num_bytes-- > 0) { 
        lseek(fd, 0, SEEK_END); 
        write(fd, "a", 1); 

寫入文件的結束的位置,因爲它是當調用lseek()作出。該文件的結尾可以在lseek()write()調用之間的時間內更改。

此代碼,對用O_APPEND打開的文件:

  while(num_bytes-- > 0) 
        write(fd, "a", 1); 

保證通過write()荷蘭國際集團與O_APPEND打開的文件的標準行爲」寫入到文件的端不管哪一端是

這就是O_APPEND標誌的整個點 - lseek()然後write()不起作用

+0

在'write()'之前,在lseek()'的幫助下,文件末尾如何在兩次調用之間改變?他們不是原子嗎? –

+1

'lseek()'是一個電話。 'write()'是另一個。序列'lseek(); write();'是兩個獨立的調用 - 兩個不能自動工作。並且文件的結尾可以在這兩個調用之間改變。再次 - 這是爲什麼存在'O_APPEND'標誌。 –