多进程读写一个文件

本文关键字:一个 文件 读写 多进程 | 更新日期: 2023-09-27 18:30:34

我有一个txt文件ABC.txt它将由多个进程读取和写入。因此,当一个进程读取或写入文件 ABC.txt 时,必须锁定文件 ABC.txt,以便任何其他进程都无法读取或写入它。我知道枚举System.IO.FileShare可能是处理此问题的正确方法。但我使用了另一种方式,我不确定它是否正确。以下是我的解决方案。

我在文件夹中添加了另一个文件Lock.txt。在读取或写入文件 ABC.txt 之前,我必须能够读取文件 Lock.txt。在我读取或写入文件 ABC.txt 之后,我必须释放该功能。以下是代码。

        #region Enter the lock
        FileStream lockFileStream = null;
        bool lockEntered = false;
        while (lockEntered == false)
        {
            try
            {
                lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None);
                lockEntered = true;
            }
            catch (Exception)
            {
                Thread.Sleep(500);
            }
        }
        #endregion
        #region Do the work
        // Read from or write to File ABC.txt
        // Read from or write to other files
        #endregion
        #region Release the lock
        try
        {
            if (lockFileStream != null)
            {
                lockFileStream.Dispose();
            }
        }
        catch
        {
        }
        #endregion

在我的电脑上,这个解决方案似乎运行良好,但我仍然无法确定它是否合适。

编辑:多进程,而不是同一进程中的多线程。

多进程读写一个文件

C# 的命名 EventWaitHandle 是这里要走的路。在每个想要使用该文件的进程中创建一个等待句柄的实例,并为其指定一个由所有此类进程共享的名称。

EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");

然后,在访问文件时等待waitHandle并在完成处理文件时,对其进行设置,以便队列中的下一个进程可以访问它。

waitHandle.WaitOne();
/* process file*/
waitHandle.Set();

命名事件等待句柄时,该名称将在操作系统中的所有进程之间共享。因此,为了避免发生冲突的可能性,请使用 guid 作为名称(上面的"SHARED_BY_ALL_PROCESSES")。

C# 中的互斥锁可以在多个进程之间共享。 下面是多个进程写入单个文件的示例:

using (var mutex = new Mutex(false, "Strand www.jakemdrew.com"))
{
    mutex.WaitOne();
    File.AppendAllText(outputFilePath,theFileText);
    mutex.ReleaseMutex();
}

您需要确保为互斥锁指定一个将在整个系统中共享的唯一名称。

此处的补充阅读:

http://www.albahari.com/threading/part2.aspx#_Mutex

您的解决方案容易出错。 您基本上已经实现了双重检查锁定(http://en.wikipedia.org/wiki/Double-checked_locking),这可能非常不安全。

更好的解决方案是引入线程隔离,即只有一个线程访问文件,并通过从队列中读取来访问文件,其他线程

在其上发出读取或写入请求(当然,队列受到线程互斥访问的保护),或者线程通过同步设备(lock部分)进行自我同步, mutices,无论如何)或使用其他一些文件访问逻辑(例如,System.IO.FileShare在这里的一些响应中出现。

如果是我,我会安装类似SQL Server Compact Edition的东西来读取/写入这些数据。

但是,如果您希望能够锁定对多个进程之间共享资源的访问,则需要使用互斥或信号量。

Mutex 类是围绕操作系统级别锁定机制的 .Net 包装器。

同步基元概述