以下测试代码(F#)未返回我期望的结果:
let safeCount() =
let n = 1000000
let counter = ref 0
let spinlock = ref <| SpinLock(false)
let run i0 i1 () =
for i=i0 to i1-1 do
let locked = ref false
try
(!spinlock).Enter locked
if !locked then
counter := !counter + 1
finally
if !locked then
(!spinlock).Exit()
let thread = System.Threading.Thread(run 0 (n/2))
thread.Start()
run (n/2) n ()
thread.Join()
!counter
Run Code Online (Sandbox Code Playgroud)
我希望SpinLock相互排除计数器,因此,它返回1,000,000的计数,但相反,它返回较小的值,好像没有发生互斥.
有什么想法有什么不对吗?
Ste*_*sen 10
SpinLock结构被复制的原因是因为!是一个函数:当作为参数传递给函数或从函数返回时(或任何其他类型的赋值),结构被复制.但是,如果直接访问ref单元格的内容,则不会进行复制.
let safeCount() =
let n = 1000000
let counter = ref 0
let spinlock = ref <| SpinLock(false)
let run i0 i1 () =
for i=i0 to i1-1 do
let locked = ref false
try
spinlock.contents.Enter locked
if !locked then
counter := !counter + 1
finally
if !locked then
spinlock.contents.Exit()
let thread = System.Threading.Thread(run 0 (n/2))
thread.Start()
run (n/2) n ()
thread.Join()
!counter
Run Code Online (Sandbox Code Playgroud)
编辑:Stephen Swensen 有一种方法可以直接访问下面的引用样式 SpinLock。!返回结构的副本,因此不应在这种情况下使用。
您可以将 SpinLock 包装在它可以工作的类中(我尝试使用静态且不可变的 SpinLock 无济于事)
type SpinLockClass() =
let s = System.Threading.SpinLock(false)
member x.Enter locked = s.Enter(locked)
member x.Exit() = s.Exit()
let safeCount() =
let n = 1000000
let counter = ref 0
let spinlock = SpinLockClass()
let run i0 i1 () =
for i=i0 to i1-1 do
let locked = ref false
try
spinlock.Enter locked
if !locked then
counter := !counter + 1
finally
if !locked then
spinlock.Exit()
let thread = System.Threading.Thread(run 0 (n/2))
thread.Start()
run (n/2) n ()
thread.Join()
!counter
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
870 次 |
| 最近记录: |