2012-07-01 30 views
10

我一直希望將System.INotifySystem.IO.MMap一起使用,以便觀察文件修改,然後快速執行差異以通過網絡發送修補程序。然而,對於System.IO.MMap的文檔中有一對夫婦關於引用透明的警告:Haskell中的引用透明和mmap

文檔狀態

這是唯一安全的針對mmap一個文件,如果你知道你是唯一的用戶。否則參照透明度可能會或可能不會受到影響。操作系統之間悲慘的語義差異很大。

是MMAP回報IO ByteString,該值肯定,當我使用這個值與putStr我期待每一次不同的結果?我認爲作者意味着在IO操作(如putStr)和崩潰期間值可能會改變?

開始編輯:來想一想,我想這個問題的答案是有點明顯的... 如果值在任何時候改變,它被拆箱後,它會有問題。

do 
    v <- mappedValue :: IO ByteString 
    putStr v 
    putStr v -- Expects the same value of v everywhere 

END-OF-EDIT

它不應該有可能獲得某種鎖在映射區域或在文件上?

或者,是否可以編寫一個函數copy :: IO ByteString -> IO ByteString,以安全的方式在當前狀態下拍攝文件的快照?

+0

聽起來像你想要的東西可以用一對簡單的管子來完成。 – leftaroundabout

+0

我以某種通用的方式「觀看」目錄中的文件。如果有任何工具觸及它們,則客戶端會自動更新。 –

+1

是否真的沒有提供類型'IO(Ptr Word8)'或類似的東西的mmap庫? –

回答

8

我認爲作者的意思是,即使在可以將其視爲普通ByteString(無IO)的提升函數內,值也可以改變。

Meory映射文件是內存區域。出於性能方面的考慮,來回複製內容並沒有多大意義(否則,只能進行普通的基於流的I/O)。所以你得到的ByteString是活的。

如果您想要創建快照,只需使用基於流的I/O即可。這就是讀取文件所做的:在內存中創建文件快照!我想一個替代方案將使用ForeignPtr接口,它不會帶有參考透明度警告。我對ForeignPtrs不熟悉,所以我不能保證它能正常工作,但它看起來很有希望,我會對它進行調查。

您也可以嘗試在您的ByteString上調用map id,但不能保證您將獲得與原始版本不同的副本。

強制性文件鎖定,特別是在Linux上,是一個混亂,最好避免。諮詢文件鎖定是可以的,除非沒有人使用它,所以它實際上不存在。

+2

我想下意識我'我對操作系統的期望有點太高。我想對待這個文件,基本上,就像多個進程之間的一個非常快速的共享內存緩存,讓操作系統可以隨意更換磁盤。更仔細地思考它我猜這似乎不太可能工作,除非所有進程明確使用共享內存映射。 –

+0

(請參閱,我希望避免觸及物理磁盤的延遲......) –