首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET 4 SpinLock

.NET 4 SpinLock
EN

Stack Overflow用户
提问于 2010-06-11 08:20:53
回答 3查看 878关注 0票数 5

下面的测试代码(F#)没有返回我期望的结果:

代码语言:javascript
复制
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的计数,但实际上,它会返回较小的值,就好像没有发生互斥一样。

知道出什么事了吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-12 05:19:54

编辑: Stephen Swensen有一种方法可以直接访问下面的引用样式SpinLock。!返回一个结构的副本,所以在这种情况下不应该使用它。

您可以将SpinLock包装在一个类中(我尝试使用静态和不可变的SpinLock,但没有效果)。

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2010-06-12 10:10:45

复制SpinLock结构的原因是!是一个函数:当将结构作为参数传递给函数或从函数返回时(或任何其他类型的赋值),结构都会被复制。但是,如果直接访问ref单元格的内容,则不会进行复制。

代码语言:javascript
复制
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
票数 10
EN

Stack Overflow用户

发布于 2010-06-11 10:06:05

SpinLock是一个值类型。当您取消引用spinLock变量(!spinLock)时,结构被复制,您进入/退出的锁现在不同了。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3019446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档