c# - 使用双缓冲技术进行并发读写?

标签 c# multithreading concurrency parallel-processing multiprocessing

我有一个相对简单的案例,其中:

  • 我的程序将通过 Websockets 接收更新,并将使用这些更新来更新它的本地状态。这些更新将非常小(通常 < 1-1000 字节 JSON 所以 < 1ms 反序列化)但会非常频繁(高达 ~1000/s)。
  • 同时,程序将从这个本地状态读取/评估并输出其结果。
  • 这两个任务应该并行运行,并将在程序的持续时间内运行,即永不停止。
  • 本地状态大小相对较小,因此内存使用不是一个大问题。

  • 棘手的部分是更新需要“原子地”发生,以便它不会从本地状态读取,例如,只写入了一半的更新。状态不限于使用原语,并且可以包含任意类 AFAICT atm,因此我无法通过使用 Interlocked 之类的简单方法来解决它。原子操作。我计划在自己的线程上运行每个任务,所以在这种情况下总共有两个线程。
    为了实现这个目标,我想使用双缓冲技术,其中:
  • 它保留了状态的两个副本,以便在写入另一个时可以读取一个。
  • 线程可以通过使用锁来传达它们正在使用的副本。即 Writer 线程在写入时锁定副本;读取器线程在完成当前副本后请求访问锁;写入器线程看到读取器线程正在使用它,因此它切换到其他副本。
  • 写入线程会跟踪它在当前副本上完成的状态更新,因此当它切换到另一个副本时,它可以“ catch ”。

  • 这是这个想法的一般要点,但实际的实现当然会有所不同。
    我试图查找这是否是一个常见的解决方案,但实际上找不到太多信息,所以我想知道以下事情:
  • 它是可行的,还是我错过了什么?
  • 有没有更好的方法?
  • 它是一个通用的解决方案吗?如果是这样,它通常被称为什么?
  • (奖金)是否有一个很好的资源我可以阅读与此相关的主题?

  • 我几乎觉得我已经陷入了一个死胡同,我找不到(因为我不知道要搜索什么)更多的资源和信息来查看这种方法是否“好”。我计划用 .NET C# 编写它,但我认为这些技术和解决方案可以翻译成任何语言。所有的见解都表示赞赏。

    最佳答案

    如果我理解正确,写入本身是同步的。如果是这样,那么也许不需要保留两个副本,甚至不需要使用锁。
    也许这样的事情可以工作?

    State state = populateInitialState();
    
    ...
    
    // Reader thread
    public State doRead() {
        return makeCopyOfState(state);
    }
    
    ...
    
    // Writer thread
    public void updateState() {
        State newState = makeCopyOfState(state);
    
        // make changes in newState
    
        state = newState;
    }
    

    关于c# - 使用双缓冲技术进行并发读写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67893189/

    相关文章:

    c# - 如何开发 Dicom 网页查看器

    c# - 如何捕获 Windows 窗体组合框中的回车键

    multithreading - 在 Go 中使用 map 时忽略 goroutine/thread-safety 的危险是什么?

    node.js - 如何在 Node Js 应用程序的多个实例之间同步对象

    c# - 使用 Connector/NET 的关联数组/哈希/哈希表

    c# - 通过代码更改音频窗口设置(从设置应用程序)

    c# - 从数据库生成 1,000,000 个文件的最佳代码

    javascript - 我如何在 JavaScript 中的线程之间进行通信?

    concurrency - 具有并发垃圾收集器的常见 Lisp 实现

    java - 为什么线程不同时运行?