【问题标题】:How to implement thread safety for the tree structure used for the following scenario?如何为以下场景使用的树结构实现线程安全?
【发布时间】:2011-12-05 13:04:44
【问题描述】:

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

总而言之,上述代码使用简单的树形结构来存储目录、子目录和文件。根是一个MemoryFolder 对象,它存储零个或多个“MemoryFolder”对象和/或MemoryFile 对象。每个MemoryFolder 对象依次存储零个或多个MemoryFolder 对象和/或MemoryFile 对象等等,直到无限深度。

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

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

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

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

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

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

【问题讨论】:

    标签: c# .net windows filesystems dokan


    【解决方案1】:

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

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

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

    如果您想跨流程共享此内容,那就另当别论了。 ReaderWriterLockSlim 不能跨进程工作。但是,您可以使用同步原语的组合来实现类似的东西,或者创建一个为请求提供服务的设备驱动程序(或服务),从而将它们保持在同一个进程中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多