2011-09-26 99 views
3

如果以下(示例)程序正在運行多個程序,需要採取哪些步驟來確保「全部」行總是總是正確附加到文件末尾同時。追加到併發環境中的文件末尾

#!/usr/bin/env python 
import random 
passwd_text=open("passwd.txt","a+") 
u=("jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8917,(234)555-0077,[email protected]:/home/jsmith:/bin/sh", 
    "jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,[email protected]:/home/jdoe:/bin/sh", 
    "xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,[email protected]:/home/xyz:/bin/sh") 
for i in range(random.randint(1,2)): 
    print >> passwd_text, random.choice(u) 
passwd_text.close() 

而且:可以「全有或全無」追加保證(在Linux/UNIX),即使磁盤已滿,或「的ulimit -f」已定?

(注意類似的問題:How do you append to a file?

+0

我不知道如果磁盤已滿,您可以如何追加數據......您可以添加更多的水到滿溢的玻璃杯嗎?除此之外,使用文件鎖定。 'flock()'是一個開始的好地方。 –

+0

@Marc B - re:「disk full」@ ...好的一點,我看到「寫入」系統調用「返回寫入的字節數,如果值爲負值,那麼系統調用返回錯誤。 。我期望「umlimit -f」在「寫入」時具有相同的效果。所以一個原子追加,可能½追加,但完全追加不能保證。 (我也不記得任何保證「全部或全部」寫在文件上的ioctl,即使「記錄」很小) – NevilleDNZ

+0

不是原子寫入嗎?你的行可能會與其他進程寫入的其他行交錯,但是行本身應該是完整的,只要你最終使用了一個'write'系統調用(這個'os.write'應該保證,即使其他類型的寫入可能會被緩衝)。如果您必須編寫多行需要保持在一起的行,請先將它們構建爲單個字符串。 –

回答

4

我認爲this "bug"在Python的正常open功能的討論表明,你沒有得到的POSIX原子保證,但怎麼做,如果你使用

with io.open('myfile', 'a') as f: 
    f.write('stuff') 

http://docs.python.org/2/library/io.html#io.open

如果工作系統正確地執行其寫入系統調用...

http://bugs.python.org/issue15723

+0

所以你說沒有理由使用fctrl.flock只要我使用io.open? –

+0

我不知道你在做什麼,所以我不能給你一個鑄鐵保證。但是在我看來,如果你使用'io.open'和''a'' append模式,你將得到一個POSIX原子寫保證。但是您應該閱讀錯誤報告和相關鏈接,以確保它適用於您的用例。這裏是龍。 – hwjp

+0

我只是有多個腳本運行,可能隨時想要更新文件中的某些內容。在這種情況下,我一直認爲「你需要一個文件鎖定」,但有時Python比我期望的更聰明:) –

3

你必須鎖定文件,以確保其他人沒有人是在同一時間寫它。有關更多詳細信息,請參閱File Lockinglockfileposixfile

更新:如果磁盤已滿,則無法向文件寫入更多數據。我不確定Python的輸出重定向的實現,但是系統調用可以寫入比請求更少的字節。

+1

特別注意與「O_APPEND」有關的「man」頁面摘錄: 如果設置了文件狀態標誌的O_APPEND標誌,則應在每次寫入之前將文件偏移設置爲文件末尾並且在更改文件偏移和寫入操作之間不會發生中間文件修改操作。 – NevilleDNZ

+0

參考這個討論 - 它看起來像python的實現不完全符合O_APPEND預期的行爲:http://bugs.python.org/issue15723 – hwjp