modifyMVar:它允许另一个写入者“进入”的位置在哪里?

huangapple go评论47阅读模式
英文:

modifyMVar: where does it allow another writer to "enter"?

问题

这是modifyMVar_函数的代码。注释中说它允许多个写操作者,并且如果发生异常,它会替换原始内容。我对代码的执行位置不是100%确定。

  1. 在哪里允许其他写操作者修改内容? 我只看到一种可能性:如果putMVar不是原子的(显然不是),并且另一个线程更快地放入自己的内容,那么这可能发生在哪里?

  2. 在异常发生时在哪里替换原始内容?我看到restore返回取出的a值。他们是否意味着在putMVar期间再次出现多个写操作者,但现在在“异常处理程序”中?

  3. 我可以将modifyMVar用作同步代码块吗?类似于Java或Python中的互斥体(mutex)?似乎是可以的,但与其他语言中的标准锁/互斥体相比可能会有什么问题?我认为io参数在执行时是互斥的,就像标准锁一样,是吗?

{-|
  这是一个对修改'MVar'内容的异常安全包装器。
  与'withMVar'类似,如果在操作过程中引发异常,'modifyMVar'将替换'MVar'的原始内容。
  只有当没有其他生产者为此'MVar'时,此函数才是原子的。
  换句话说,它不能保证在'modifyMVar_'有机会写入MVar之前,MVar的值是否已经被另一个线程的写操作修改。
-}
{-# INLINE modifyMVar_ #-}
modifyMVar_ :: MVar a -> (a -> IO a) -> IO ()
modifyMVar_ m io =
  mask $ \restore -> do
    a  <- takeMVar m
    a' <- restore (io a) `onException` putMVar m a
    putMVar m a'
英文:

This is the code of modifyMVar_. The comment says it allows multiple writers. And that it replaces the original content if an exception happens. I am not 100% sure about my understanding where it happens looking at the code.

  1. where does it allow another writer to alter the content? I see only one possibility: if putMVar is not atomic (obviously it is not) and another thread puts its own content faster. Is it the place?
  2. where does it replace the original content on exception? I see that restore returns taken a value back. Do they mean again possibility of multiple writers during putMVar but now in the "exception handler"?
  3. Can I use modifyMVar as a synchronized code block? Like a mutex in Java or in Python? It seems yes, but what could be a problem in comparison with a standard lock/mutex in other languages? I think the io argument is executed mutually exclusive as in a standard lock, is not it?
{-|
  An exception-safe wrapper for modifying the contents of an &#39;MVar&#39;.
  Like &#39;withMVar&#39;, &#39;modifyMVar&#39; will replace the original contents of
  the &#39;MVar&#39; if an exception is raised during the operation.  This
  function is only atomic if there are no other producers for this
  &#39;MVar&#39;. In other words, it cannot guarantee that, by the time
  &#39;modifyMVar_&#39; gets the chance to write to the MVar, the value
  of the MVar has not been altered by a write operation from another thread.
-}
{-# INLINE modifyMVar_ #-}
modifyMVar_ :: MVar a -&gt; (a -&gt; IO a) -&gt; IO ()
modifyMVar_ m io =
  mask $ \restore -&gt; do
    a  &lt;- takeMVar m
    a&#39; &lt;- restore (io a) `onException` putMVar m a
    putMVar m a&#39;

答案1

得分: 3

  1. 这部分文档允许其他编写者修改内容的位置是:

    • modifyMVar_ 的理念是,如果有多个并发的 modifyMVar_,其中一个将运行其 takeMVar,现在 MVar 为空,所以所有其他 modifyMVar_ 将在 takeMVar 上阻塞。这保证了对相同变量的 modifyMVar_ 将按顺序运行,因此是原子的。
    • 如果另一个线程直接使用 putMVar(而不是通过 modifyMVar_ 间接使用),这将解锁等待的 modifyMVar_,从而破坏了原子性保证。
  2. 它在异常情况下替换原始内容的位置是:

    • action `onException` putMVar m a 运行 action,如果它引发异常,在重新引发异常之前会运行 putMVar m a
  3. 我可以将 modifyMVar 用作同步的代码块吗?

    • 是的,MVar () 是一个互斥锁。
英文:

> 1. where does it allow another writer to alter the content?

I assume you are referring to this part of the documentation:

> This function is only atomic if there are no other producers for this MVar.

The idea behind modifyMVar_ is that if there are multiple concurrent modifyMVar_, one of them will run its takeMVar, and now the MVar is empty so all the other modifyMVar_ will block on takeMVar. This guarantees that modifyMVar_ (on the same variable) will run sequentially, and therefore atomically.

If another thread uses putMVar directly (instead of indirectly via modifyMVar_), that will unlock a waiting modifyMVar_, which breaks the atomicity guarantee.

> 2. where does it replace the original content on exception?

action `onException` putMVar m a runs action and if it raises an exceptions, runs putMVar m a before re-raising the exception.

> 3. Can I use modifyMVar as a synchronized code block?

Yes, an MVar () is a mutex.

huangapple
  • 本文由 发表于 2023年5月29日 21:11:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357687.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定