Re:Fix your damned data races
by elihu on Tuesday February 24, 2015 @01:47PM
(#9102639)
It's possible to write race-prone code in Haskell if you have several threads reading and writing IORefs concurrently in the IO monad. There are plenty of safer alternatives, though, so there's not much point in writing software that way unless you're actually trying to create a race.
MVars can deadlock, but you can't accidentally mutate/read a value without taking the lock (unless you use IORefs in conjunction with MVars).
STM handles races by detecting them and re-starting a transaction if a race occurs, so races aren't possible. (Accessing IORefs is disallowed by the type system inside an STM transaction, so you're safe there.) STM also isn't susceptible to deadlocks, so it's generally the safest option if you need non-deterministic threading, and invoking transactions from the IO monad fits with the structure of your program.
There's also par/seq, strategies, and the Par monad which are great for parallel computation and aren't prone to races or deadlocks. They can be called from anywhere in a Haskell program and are deterministic -- they're guaranteed to always return the same result when given the same inputs. Results cannot depend on the order in which threads are scheduled.
MVars can deadlock, but you can't accidentally mutate/read a value without taking the lock (unless you use IORefs in conjunction with MVars).
STM handles races by detecting them and re-starting a transaction if a race occurs, so races aren't possible. (Accessing IORefs is disallowed by the type system inside an STM transaction, so you're safe there.) STM also isn't susceptible to deadlocks, so it's generally the safest option if you need non-deterministic threading, and invoking transactions from the IO monad fits with the structure of your program.
There's also par/seq, strategies, and the Par monad which are great for parallel computation and aren't prone to races or deadlocks. They can be called from anywhere in a Haskell program and are deterministic -- they're guaranteed to always return the same result when given the same inputs. Results cannot depend on the order in which threads are scheduled.
tl;dr: don't use IORefs and you should be fine