Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing a mvar between threads

I'm trying to make a program that print arrows until the user press enter (see code bellow).

The problem is that when I press enter, I see the "stop" string in the console, but it doesn't change the value of m in the outputArrows function.

How can I share the state?

import Control.Concurrent
import Control.Concurrent.Async
import Control.Monad

waitForInput m = do
    getLine
    putStrLn "stop"
    putMVar m True

outputArrows m = do
    stop <- readMVar m
    unless stop $ do
        threadDelay 1000000
        putStr ">"
        outputArrows m

main = do
    m <- newMVar False
    th1 <- async (waitForInput m)
    th2 <- async (outputArrows m)
    wait th1
    wait th2
like image 460
Bruno Avatar asked Dec 03 '25 23:12

Bruno


1 Answers

Your putMVar doesn't actually put a new value in the MVar but blocks indefinitely. MVars are like boxes that can hold only a single value. If you want to replace the value, you need to take out the old value first.

If you don't need the blocking behavior of MVar, you should just use a regular IORef or possibly a TVar if you need to ensure that more complex operations run atomically.

like image 162
shang Avatar answered Dec 06 '25 11:12

shang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!