sto cercando di capire l'esempio MVAR nel GHC latest docs -Aiuto comprensione esempio MVAR in Haskell
data SkipChan a = SkipChan (MVar (a, [MVar()])) (MVar())
newSkipChan :: IO (SkipChan a)
newSkipChan = do
sem <- newEmptyMVar
main <- newMVar (undefined, [sem])
return (SkipChan main sem)
putSkipChan :: SkipChan a -> a -> IO()
putSkipChan (SkipChan main _) v = do
(_, sems) <- takeMVar main
putMVar main (v, [])
mapM_ (sem -> putMVar sem()) sems
getSkipChan :: SkipChan a -> IO a
getSkipChan (SkipChan main sem) = do
takeMVar sem
(v, sems) <- takeMVar main
putMVar main (v, sem:sems)
return v
dupSkipChan :: SkipChan a -> IO (SkipChan a)
dupSkipChan (SkipChan main _) = do
sem <- newEmptyMVar
(v, sems) <- takeMVar main
putMVar main (v, sem:sems)
return (SkipChan main sem)
Capisco la maggior parte del programma, ma per due domande -
- sono operazioni come
putSkipChan
atomico? Sembra di evitare il blocco suputMVar
facendo prima untakeMVar
. Ma non fallirebbe se qualcos'altro chiamaputMVar
dopo iltakeMVar
ma prima delloputMVar
? In questi casi, sembra che il programma bloccherà per sempre. - Perché
dupSkipChan
aggiungisem
all'elenco di semafori nelloSkipChan
? Non è quello fatto dagetSkipChan
. Mi sembra che chiamaredupSkipChan
seguito dagetSkipChan
(che sembra essere quello che hai avere da fare per avere più lettori) causerebbe un blocco quandoputSkipChan
tenta di risvegliare lo stesso semaforo due volte?