多进程读写一个文件
本文关键字:一个 文件 读写 多进程 | 更新日期: 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 包装器。
同步基元概述