Home > Enterprise >  How to use Atomics Counter for counting operation order of randomly occuring operations on different
How to use Atomics Counter for counting operation order of randomly occuring operations on different

Time:09-17

What I'd like to do is something like this where every time one of these print actions occurs it updates the counter to ensure that the next subsequent occurrence of a print action will always have the correct order in which it occurred among any of the possible print actions that may occur across multiple threads shown by the counter. The problem in my example is that if the IORef is read at the same time between threads then two or more print actions will have the same counter value. From what I've read it seems that using the Data.Atomics.Counter library would solve this problem but i am having a really hard time understanding how to use it do so. Can anyone show me an example or try to explain it to me please?

main = do
         myref <- newIORef 1 :: IO (IORef Int)
         void(forkIO (forever $ do ref <- readIORef myref
                                   print ("hi "    show (ref))
                                   modifyIORef myref ( 1) ))
         void(forkIO (forever $ do ref <- readIORef myref
                                   print ("hey "    show (ref))
                                   modifyIORef myref ( 1) ))
         forever $ do ref <- readIORef myref
                      print ("hello "    show (ref))
                      modifyIORef myref ( 1) 

CodePudding user response:

I would use an MVar for this.

inc mvar = forever $ do
    v <- takeMVar mvar
    print v
    putMVar mvar (v 1)

main = do
    mvar <- newMVar 1
    forkIO (inc mvar)
    forkIO (inc mvar)
    inc mvar

It is important that the print occur between takeMVar and putMVar, while the MVar is empty; otherwise another thread may empty the MVar and execute its print.

CodePudding user response:

You could use atomicModifyIORef'. It would look something like:

increment ref = forever do
  val <- atomicModifyIORef' ref \old -> (old   1, old)
  print val

main = do
  ref <- newIORef 0
  forkIO $ increment ref
  forkIO $ increment ref
  increment ref
  • Related