【问题标题】:Concurrent file write并发文件写入
【发布时间】:2009-07-21 16:18:59
【问题描述】:

如何写入可由多个源(可能以并发方式)访问的文本文件以确保不会丢失任何写入操作?

例如,如果两个不同的进程同时写入文件,这可能会导致问题。简单的解决方案(不是很快也不是很优雅)是在开始进程时锁定文件(创建一个 .lock 文件或类似文件)并在写入完成时释放它(删除锁)。

开始写的时候,我会检查.lock文件是否存在并延迟写直到文件被释放。

对于这种情况,建议遵循什么模式?

谢谢

编辑 我的意思是进程,比如来自不同客户端、不同用户等的不同程序,而不是同一个程序中的线程

【问题讨论】:

  • 你的意思是两个不同的进程或线程?因为如果您想为几个进程安全访问一个文件,那么如果不使用一些互斥锁或其他进程间锁定机制,您将无能为力。

标签: c# logging concurrency


【解决方案1】:

考虑使用一个简单的数据库。您将相对容易地获得所有这些内置安全性。

【讨论】:

    【解决方案2】:

    在进程之间同步访问的最快方法是使用互斥锁/信号量。该线程回答了如何使用它们来模拟读写器锁定模式: Is there a global named reader/writer lock?

    【讨论】:

    • 有一种方法可以使用可以从多个进程引用的命名互斥锁。如果所有文件访问都来自单个进程(但多个线程),那么它们都可以指向同一个互斥体来获取锁。
    • Kieveli - 作者的意思是不同的进程,因此 - Mutexes / Semaphoers 是最明显的选择,这就是我写它们的原因,如果我们要讨论线程,包括互斥锁和 ReadWriteLock 等更简单的结构会工作的。
    【解决方案3】:

    我建议使用 ReaderWriterLock。它是为多个读者设计的,但确保只有一个作家可以在任何时候写入数据MSDN。

    【讨论】:

    • 不要使用 ReaderWriterLock,它的性能很差。在 Wintellect PowerThreading 库中使用 ReaderWriterLockSlim 或 Jeffrey Richter 的锁之一。
    • 两者都不要使用;)。读写器锁、监视器(锁)等不具备进程间锁的能力,这就是作者的意思(比如,如果两个不同的进程同时写入文件)?
    • 不要使用进程间锁定。切换到一次只运行一个进程的操作系统。
    • 是的,让我们开始使用 MS-DOS
    • Ravadre,确实它们不能跨进程工作,但是这个答案在编辑之前就已经存在了。我会把它留在这里,以防其他人偶然发现它寻找相同的流程解决方案。
    【解决方案4】:

    我会看类似Command Pattern 的东西来做这件事。并发写入将是数据完整性的噩梦。

    基本上你使用这种模式来排队你的写命令,以便它们按照请求的顺序完成。

    您还应该使用ReaderWriterLock 来确保您可以在写入时从文件中读取。这将是命令模式背后的第二道防线,因此在给定时间只有一个线程可以写入文件。

    【讨论】:

    • +1 用于推荐使用队列,但之后我几乎因为 RW-lock 评论而对你发出警告。队列管理它自己的锁......你还锁定什么?
    • 我的意思更多是为了第二道防线。事后看来,我认为有比使用 RWL 更好的方法,但我不想让他过早优化,尽管 RWL 的性能下降。但是我开始怀疑他是否意味着多个不同的进程/应用程序访问和写入文件,如果是这样,那么这两个都将毫无价值。
    【解决方案5】:

    您也可以尝试锁定。这很简单——“锁定确保一个线程不会进入临界区,而另一个线程处于代码的临界区。如果另一个线程试图进入锁定的代码,它将等待(阻塞)直到对象被释放。”

    http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.71%29.aspx

    【讨论】:

    • 实际上,使用监视器(锁)比 ReaderWriterLockSlim.EnterWriteLock + ExitLock 更便宜。使用 rw 锁很好,当你的读者和作者很少时,但在这种情况下,你宁愿不从文件中读取,因为它只是一个日志文件,你会主要写入它,所以你需要使用 WriteLocks无论如何->因此,您将无法同时访问资源->因此,您可以使用常规锁。更不用说,两者都不适用于进程间同步。
    【解决方案6】:

    我还建议您寻找在关键部分中拥有多个读者且只有 1 个作者的示例,这是一篇具有良好解决方案的短论文 http://arxiv.org/PS_cache/cs/pdf/0303/0303005v1.pdf

    或者,您可以考虑在每次请求文件时创建文件副本,以及何时将任何更改写入与原始文件合并的文件。

    【讨论】:

      猜你喜欢
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-10-20
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多