10

我希望同时使用System.INotifySystem.IO.MMap来监视文件修改,然后快速执行差异以通过网络发送补丁。但是,在System.IO.MMap的文档中,有几个关于引用透明度的警告:

该文件指出

只有当您知道自己是唯一用户时,才可以安全地映射文件。否则,参考透明度可能会或可能不会受到损害。遗憾的是,操作系统之间的语义差异很大。

MMap 返回的值IO ByteString肯定是,当我使用这个值时,putStr我每次都期待不同的结果?我假设作者的意思是在 IO 操作期间该值可能会发生变化,例如putStr崩溃?

开始编辑:想一想,我想这部分问题的答案有些明显......如果在拆箱后的任何时间值发生变化,那将是有问题的。

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

编辑结束

难道不能在映射区域或文件上获得某种锁吗?

或者,是否可以编写一个函数copy :: IO ByteString -> IO ByteString以安全的方式获取文件当前状态的快照?

4

1 回答 1

9

我认为作者的意思是,即使在可以将其视为普通ByteString(无 IO)的提升函数内部,该值也可以更改。

The meory mapped file is a region of memory. It doesn't make much sense to copy its content back and forth, for performance reasons (otherwise one could just do plain old stream-based I/O). So the ByteString you are getting is live.

If you want to have a snapshot, just use a stream-based I/O. That's what reading a file does: creates a file snapshot in the memory! I guess an alternative would be using the ForeignPtr interface which does not carry the referential transparency warning. I'm not familiar with ForeignPtrs so I cannot guarantee it will work, but it looks promising and I would investigate it.

You can also try calling map id on your ByteString but it is not guaranteed you will get a copy distinct from the original.

Mandatory file locking, especially on Linux, is a mess that is better avoided. Advisory file locking is OK, except nobody is using it, so it effectively does not exist.

于 2012-07-01T18:52:33.183 回答