admin管理员组文章数量:1336380
The documentation for atomicModifyIORef states the following:
This function is useful for using IORef in a safe way in a multithreaded program. If you only have one IORef, then using atomicModifyIORef to access and modify it will prevent race conditions.
Extending the atomicity to multiple IORefs is problematic, so it is recommended that if you need to do anything more complicated then using MVar instead is a good idea.
I'm not sure to understands what this precisely mean. Suppose for instance I have two completely independent IORefs, is atomicity not guaranteed ? If this is the case, what is the point of atomicModifyIORef
? It seems very dangerous to use...
Now I'm aware of STM, but for CAS (compare-and-swap) implementation, which is what I need, it apparently runs slower. Indeed, this article says, p. 5
In terms of performance, the atomicModifyIORef version of CAS is vastly superior to the STM encoding of CAS.
So my questions are the following :
- When exactly is the atomicity broken when using
atomicModifyIORef
multipleIORefs
in a multithreaded environment ? - Why is it "problematic" to extend atomicity to multiple IORefs ? Any reference on the subject ?
The documentation for atomicModifyIORef states the following:
This function is useful for using IORef in a safe way in a multithreaded program. If you only have one IORef, then using atomicModifyIORef to access and modify it will prevent race conditions.
Extending the atomicity to multiple IORefs is problematic, so it is recommended that if you need to do anything more complicated then using MVar instead is a good idea.
I'm not sure to understands what this precisely mean. Suppose for instance I have two completely independent IORefs, is atomicity not guaranteed ? If this is the case, what is the point of atomicModifyIORef
? It seems very dangerous to use...
Now I'm aware of STM, but for CAS (compare-and-swap) implementation, which is what I need, it apparently runs slower. Indeed, this article says, p. 5
In terms of performance, the atomicModifyIORef version of CAS is vastly superior to the STM encoding of CAS.
So my questions are the following :
- When exactly is the atomicity broken when using
atomicModifyIORef
multipleIORefs
in a multithreaded environment ? - Why is it "problematic" to extend atomicity to multiple IORefs ? Any reference on the subject ?
1 Answer
Reset to default 1A modify of an IORef embodies a read followed by a write. So if you write a naïve implementation of modify like this:
do
old <- readIORef myVar
writeIORef myVar $ f old
then you have a potential race condition if two threads execute this code at the same time.
atomicallyModifyIORef
guarantees to do this operation atomically, so the first thread will complete the update before the second one starts.
However if you have two IORefs then you can't do it this way. Say you want to transfer some value from one to the other, you can decrement one atomically, and then increment the other atomically, but between those two operations there is a period when the sum is in transit, and so the state is inconsistent.
Extending atomicity to multiple IORefs would require a lot of extra overhead for tracking which IORefs are included in a transaction, storing values in case of a rewind etc. This would be paid for any use of IORefs even if no atomic transactions are done. So its a bad idea. That's what TRefs are for.
本文标签: multithreadingAtomically modifying multiple IORefs in concurrent HaskellStack Overflow
版权声明:本文标题:multithreading - Atomically modifying multiple IORefs in concurrent Haskell - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742405697a2468773.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
IORef
s, each CAS is atomic independently, but if you want to change the value of bothIORef
s in a way such that in the rest of the program either both changes have happened or neither have, that is very hard to get right. There's all sorts of low-level memory-op reordering, cache-coherency, and similar wrinkles not to mention the high-level issue of designing a protocol even if you make very strong assumptions about memory ordering. – Daniel Wagner Commented Nov 19, 2024 at 19:01IORef
API doesn't provide a way of "doing IO" while atomically modifying theIORef
. The functions that are applied to theIORef
value are pure. So it's not even possible to modify oneIORef
while in the process of modifying another. (MVar
s do let you performIO
effects while "holding" theMVar
.) – danidiaz Commented Nov 19, 2024 at 19:56