multithreading - F# 同步访问列表

标签 multithreading f# immutability agent

假设我在系统中有一个整数列表:

let mutable data: int list = [1; 2; 3; 4; 5]

通过相对 更新(通过添加元素)少数 生产者和消费者 手数的消费者。

注意:如果消费者收到稍微过时的数据也没关系。

同步访问此变量的正确方法是什么?

一个 ) 安全的方法是将此变量包装到代理中并通过序列化消息访问它,我们甚至不需要 mutable修改器在这里。但是这种方法似乎不是最优的,因为它会不必要地使所有读取访问同步。

) AFAIK 引用分配在 .NET 中是原子的,因此在一个发布者和所有消费者之间,一个简单的分配就足够了:

发布者:data <- newItem :: data
消费者:data |> process
那么发布者之间的简单锁定就足以结束这个工作流程?
let monitor = object()

发布者:lock monitor (fun () -> data <- newItem::data)
我的假设是否正确?哪种方法是首选并且对 F# 更惯用?还有更好的选择吗?

最佳答案

您可以使用 Interlocked.CompareExchange在不显式锁定的情况下处理发布:

let mutable data = [1;2;3;4;5]

let newValue = 0

// To publish:
let mutable tmp = data;
while not(tmp.Equals(Interlocked.CompareExchange(&data, newValue::data, tmp))) do
    tmp <- data

如果您有同步的编写器,这可能会带来一点好处。

如果您决定确实希望消费者始终拥有最新数据,请使用 ReaderWriterLockSlim 将允许您完全同步数据,而无需在每次调用时强制读取阻塞。

这可能看起来像:
let mutable data = [1;2;3;4;5]
let rwl = ReaderWriterLockSlim()

let newValue = 0

// To publish:
let publish newValue =
    rwl.EnterWriteLock()
    try
        data <- newValue :: data
    finally
        rwl.ExitWriteLock()

// To read:
let readCurrent =
    rwl.EnterReadLock()
    try
        data
    finally
        rwl.ExitReadLock()

关于multithreading - F# 同步访问列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23661863/

相关文章:

f# - 如何创建实现 IDictionary <'K, ' V> 和 IEnumerable<'V> 的类型

.NET:GC 何时运行?内存泄漏?

java - 为什么即使不使用 volatile,在一个线程中修改共享变量也会影响另一个线程?

c - 如何获取每个连接的文件名(网页)

f# - FSharp 嵌入式 API 添加变量

c# - F# 接口(interface)实现错误

rust - 不可变对象(immutable对象)根据函数签名更改为可变对象

javascript - 复制对象数组并在不修改原始数组的情况下进行更改

C 多线程 : Race condition scenarios

java - 如何在线程中继续尝试获取 Java DatagramSocket?