【问题标题】:Referential transparency and mmap in HaskellHaskell 中的引用透明度和 mmap
【发布时间】:2012-07-01 17:01:06
【问题描述】:

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

文档说明

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

MMap 返回的值是IO ByteString,当我将这个值与putStr 一起使用时,我每次都会期待不同的结果吗?我假设作者的意思是在putStr这样的IO操作期间值可能会发生变化并崩溃?

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

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

编辑结束

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

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

【问题讨论】:

标签: haskell file-io io mmap virtual-memory


【解决方案1】:

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

内存映射文件是一个内存区域。出于性能原因,来回复制其内容没有多大意义(否则可以只做普通的旧的基于流的 I/O)。所以你得到的 ByteString 是活的。

如果您想要快照,只需使用基于流的 I/O。这就是读取文件的作用:在内存中创建文件快照!我想另一种选择是使用不带有引用透明度警告的ForeignPtr 接口。我对 ForeignPtrs 不熟悉,所以我不能保证它会起作用,但它看起来很有希望,我会调查它。

您也可以尝试在您的 ByteString 上调用 map id,但不能保证您会得到与原始文件不同的副本。

强制文件锁定,尤其是在 Linux 上,是一个最好避免的混乱。建议文件锁定是可以的,除了没有人使用它,所以它实际上不存在。

【讨论】:

  • 我想潜意识里我对我的操作系统的期望有点过高。基本上,我想将文件视为多个进程之间非常快速的共享内存缓存,让操作系统随意处理将更改刷新到磁盘。仔细考虑一下,我猜这似乎不太可能工作,除非所有进程都明确使用共享内存映射。
  • (看,我希望避免在接触物理磁盘时产生延迟......)
猜你喜欢
  • 2012-04-23
  • 2012-12-22
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 2011-08-07
  • 2011-12-06
相关资源
最近更新 更多