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

发布于 2024-12-09 07:21:15 字数 1262 浏览 1 评论 0 原文

我正在利用位于以下链接的 C# 代码来实现 Ram 磁盘项目。

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

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

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

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

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

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

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

I am making use of the C# code located at the following links to implement a Ram-disk project.

  • Link to description of source code
  • Link to source code

As a summary, the code indicated above makes use of a simple tree structure to store the directories, sub-directories and files. At the root is a MemoryFolder object which stores zero or more 'MemoryFolder' objects and/or MemoryFile objects. Each MemoryFolder object in turn stores zero or more MemoryFolder objects and/or MemoryFile objects and so forth up to an unlimited depth.

However, the code is not thread safe. What is the most elegant way of implementing thread safety? In addition, how should the following non-exhaustive list of multithreading requirements for a typical file system be enforced by using the appropriate locking strategy?

  1. The creation of two different folder (each by a different thread) simultaneously under the same
    parent folder can occur concurrently if the thread safe
    implementation allows it. Otherwise, some locking strategy should be
    implemented to only allow sequential creation.

  2. None of the direct or indirect parent folders of the folder
    containing a specific file (that is currently read by another
    thread) propagating all the way up to the root folder can be moved
    or deleted by another thread until the ReadFile thread completes its
    execution.

  3. With regards to each unique file, allows concurrent access for multiple ReadFile threads but restricting access to a single WriteFile thread.

  4. If two separate ReadFile threads (fired almost simultaneously),
    each from a different application attempts to create a folder with
    the same name (assuming that the folder does not already exist
    before both threads are fired), the first thread that enters the
    Ram-Disk always succeeds while the second one always fails. In other
    words, the order of thread execution is deterministic.

  5. The total disk space calculation method GetDiskFreeSpace running
    under a separate thread should not complete its execution until all
    WriteFile threads that are already in progress complete its execution. All subsequent WriteFile threads that have not begun executing are blocked until the GetDiskFreeSpace thread completes its execution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小草泠泠 2024-12-16 07:21:15

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

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

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

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

The easiest way to do this would be to protect the entire tree with a ReaderWriterLockSlim. That allows concurrent access by multiple readers or exclusive access by a single writer. Any method that will modify the structure in any way will have to acquire the write lock, and no other threads will be allowed to read or write to the structure until that thread releases the write lock.

Any thread that wants to read the structure has to acquire the read lock. Multiple readers can acquire the read lock concurrently, but if a thread wants to acquire the write lock--which means waiting until all existing read locks are released.

There might be a way to make that data structure lock-free. Doing so, however, could be quite difficult. The reader/writer lock will give you the functionality you want, and I suspect it would be fast enough.

If you want to share this across processes, that's another story. The ReaderWriterLockSlim doesn't work across processes. You could, however, implement something similar using a combination of the synchronization primitives, or create a device driver (or service) that serves the requests, thereby keeping it all in the same process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文