[Haskell-cafe] Is it safe to create global variables using unsafePerformIO?
Alexander Alexeev
mail at eax.me
Wed Jan 29 07:32:26 UTC 2014
Hello!
Lets consider the following code:
import Control.Concurrent
import Control.Concurrent.STM
import System.IO.Unsafe (unsafePerformIO)
{-# NOINLINE counter #-}
counter :: TVar Int
counter = unsafePerformIO $ newTVarIO 0
incCounter :: IO Int
incCounter = do
r <- atomically $ do
t <- readTVar counter
let t' = t + 1
writeTVar counter t'
return t'
return r
main :: IO ()
main = do
n1 <- incCounter
print n1
n2 <- incCounter
print n2
n3 <- incCounter
print n3
This program prints:
1
2
3
So we have a "global variable". Do I right understand that newTVarIO
creates TVar and RTS memoizes it since 'counter' function is pure? If
it's true, could it happen that under some circumstances memoized value
will be deleted from memory? Or Haskell keeps all memoized values
forever?
Another issue which I'm afraid of --- would the given code be safe in
multithread application? For example, is it possible to encounter a
race condition if two threads will try to create a new counter in the
same time?
Is there any other problems which should be taken in account?
--
Best regards,
Alexander Alexeev
http://eax.me/
More information about the Haskell-Cafe
mailing list