如何实现用于以下场景的树结构的线程安全性?

时间:2011-10-11 18:17:30

标签: c# .net windows filesystems dokan

我正在使用位于以下链接的C#代码来实现Ram-disk项目。

  • Link对源代码的描述
  • Link来源代码

总之,上面指出的代码使用简单的树结构来存储目录,子目录和文件。根目录是一个MemoryFolder对象,它存储零个或多个“MemoryFolder”对象和/或MemoryFile个对象。每个MemoryFolder对象反过来存储零个或多个MemoryFolder个对象和/或MemoryFile个对象,直至无限深度。

但是,代码不是线程安全的。实现线程安全的最优雅方式是什么?此外,如何通过使用适当的锁定策略来强制执行以下针对典型文件系统的多线程要求的非详尽列表?

  1. 同时创建两个不同的文件夹(每个由不同的线程组成) 如果线程安全,父文件夹可以同时发生 实现允许它。否则,应该采取一些锁定策略 实现只允许顺序创建。

  2. 该文件夹的直接或间接父文件夹均不包含 包含特定文件(当前由另一个文件读取) 线程)一直传播到根文件夹可以移动 或者被另一个线程删除,直到ReadFile线程完成它 执行。

  3. 关于每个唯一文件,允许多个ReadFile线程的并发访问,但限制对单个WriteFile线程的访问。

  4. 如果两个单独的ReadFile个线程(几乎同时触发), 每个来自不同的应用程序尝试创建一个文件夹 相同的名称(假设该文件夹尚不存在 在两个线程被触发之前),进入的第一个线程 Ram-Disk总是成功,而第二个总是失败。其他 单词,线程执行的顺序是确定性的。

  5. 运行的磁盘空间总计算方法GetDiskFreeSpace 在一个单独的线程下不应该完成它的执行直到所有 正在进行的WriteFile个线程完成其执行。在WriteFile线程完成执行之前,所有未开始执行的GetDiskFreeSpace个线程都将被阻塞。

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用ReaderWriterLockSlim保护整个树。这允许多个读者的并发访问或单个编写者的独占访问。任何以任何方式修改结构的方法都必须获取写锁,并且在该线程释放写锁之前,不允许其他线程读取或写入结构。

任何想要读取结构的线程都必须获取读锁定。多个读取器可以同时获取读锁定,但是如果一个线程想要获取写锁定 - 这意味着要等到所有现有的读锁定被释放。

可能有一种方法可以使数据结构无锁。但是,这样做可能非常困难。读取器/写入器锁将为您提供所需的功能,我怀疑它会足够快。

如果你想跨进程分享这个,那就是另一个故事。 ReaderWriterLockSlim不适用于流程。但是,您可以使用同步原语的组合实现类似的功能,或者创建一个服务于请求的设备驱动程序(或服务),从而将它们保存在同一个进程中。