以下测试代码(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

我希望SpinLock可以互斥该计数器,因此,它返回的计数为1,000,000,但是,它返回的值较小,就好像没有互斥发生一样。

任何想法出什么事了吗?

最佳答案

编辑:
斯蒂芬·斯文森(Stephen Swensen)有一种方法可以直接访问下面的ref风格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

关于.NET 4自旋锁,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3019446/

10-13 06:01