【发布时间】:2021-10-10 11:36:06
【问题描述】:
我正在尝试编写一个 F# 计算表达式,该表达式仅允许从临界区读取和写入线程安全变量。
我有一个类型 ThreadSafeVar<'t> 包装了一个值 CriticalSection<'t> 和一个计算表达式构建器 LockContext,如下所示:
// wraps a value and restricts access to it
type ThreadSafeVar<'t> (value: 't) =
member val internal Value = value with get, set
// Encapsulates a critical section
type CriticalSection<'t> =
private
{ LockObj: obj
fn: unit -> 't }
static member Lock(lc: CriticalSection<'t>) = lock lc.LockObj lc.fn
// Expression builder for a locked context
type LockContext () =
member internal this.SyncRoot = obj()
member this.Return(value: 'v) = value
member this.ReturnFrom(value: ThreadSafeVar<'t>) = value.Value
member __.Bind(value: ThreadSafeVar<'t>, fn: 't -> 'u) = fn value.Value
// returns a CriticalSection
member this.Run(fn : unit -> 'u) = { LockObj = this.SyncRoot
fn=fn }
.
.
.
感谢Bind,从锁上下文中读取线程安全值非常简单。例如
let lockedInt = ThreadSafeVar(1) // create a thread-safe variable
let context = LockContext()
let wrapperVal = context {
let! i = lockedInt // get the wrapper value inside lockedInt
return i
} |> CriticalSection.Lock
但我很难理解如何实现从 LockContext 实例中设置值的方法。我因此采取的方法是实现一个custom operation,例如,称为setVal。到目前为止,我已经将我的尝试包括在内,但我担心它们只会让水变得浑浊。似乎自定义操作对迄今为止在表达式中构建的计算进行操作,编码为元组,但我认为在我的情况下不需要这样做。
任何提示、指向资源或直接帮助将不胜感激。
【问题讨论】:
标签: multithreading functional-programming f# thread-safety