多进程读写一个文件

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

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

#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 

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

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

C#的名字叫EventWaitHandle就是去的地方。 在每个想要使用该文件的进程中创建一个等待句柄实例,并为其指定一个由所有此类进程共享的名称。

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

然后,当在waitHandle上访问文件wait并完成处理文件时,设置它以便队列中的下一个进程可以访问它。

 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部分,突变体等)或使用其他一些文件访问逻辑来同步自己(例如, System.IO.FileShare在这里引起了一些反响。)

C#有一个内置lock ,您可以通过创建一个所有线程都可以访问的静态对象来使用它:

 private static object lockObject {get;set;} public static object LockObject {get{return lockObject ?? lockObject = new object();}} void YourMethod() { lock(LockObject) // all other threads will wait for y { using(var lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None)) { //Do what you need with the file. } } } 

这为您的问题创建了一个Thread Safe方法。

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

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

Mutex类是围绕OS级别锁定机制的.Net包装器。

同步原语概述