TVar конструктор? Я не могу получить TVar
Я новичок в haskell и stm, и я хотел сделать простой рулок. Сначала я создал 4 основных функции (wlock, wunlock, rlock, runlock), для которых требуется 2 TVar Integeres: количество потоков чтения и записи потоков.
На данный момент я не могу использовать его по назначению. Я пытаюсь скомпилировать вот так
v1 <- atomically(newTVar 0);
v2 <- atomically(newTVar 0);
wlock v1 v2 -- wlock :: TVar Integer -> TVar Integer -> IO ()
что, конечно, некрасиво, но это работает (не знаю почему, потому что атомно возвращается IO (TVar a)
вместо TVar a
)
Что я хочу:
Я пытаюсь сделать это лучше, скрывая ценности. Я где-то читал, что монады могут быть подходящим способом, но я еще не изучал их. Вместо этого я пытаюсь сделать новый тип Rwlock как
data Rwlock = Rwlock { readCant :: TVar Integer
,writeCant :: TVar Integer
}
и конструктор, так что я могу сделать что-то вроде этого:
import Rwlock
do{
a = rwconst;
forkIO(reader a);
forkIO(writer a);
}
куда читатель позвонит rlock a
и писатель wlock a
,
Эта проблема:
Я не могу сделать конструктор. Это то, что я пытаюсь (игнорировать maxLectores
)
(А):
rwconst :: Integer -> Rwlock
rwconst n = Rwlock {readCant = TVar 0, writeCant = TVar 0, maxLectores = n}
{-rwconst n = Rwlock {readCant = atomically(newTVar 0), writeCant = atomically(newTVar 0), maxLectores = n}-}
Но конструктор TVar не экспортируется, и ничего не возвращает TVar. Я не знаю, почему первый блок кода работает, когда я делаю wlock v1 v2
, но так не бывает.
И (Б):
rwconst :: Integer -> Rwlock
rwconst n = do
a <- (atomically(newTVar 0));
Rwlock {readCant = a, writeCant = a, maxLectores = n}
Здесь у Rwlock нет проблем, но оператор do возвращает IO() вместо Rwlock, как я хочу, и я не могу найти, как это сделать:(
Кто-нибудь может сказать мне, как это сделать? Заранее спасибо.
1 ответ
Выделение блокировок требует ввода-вывода, и вы не можете обойти это. Так что признай это в своем действии:
rwconst :: Integer -> IO Rwlock
rwcost n = do
rcount <- newTVarIO 0
wcount <- newTVarIO 0
return Rwlock { readCant = rcount, writeCant = wcount, maxLectores = n }
Затем в main
Вы можете написать что-то вроде этого:
main = do
a <- rwconst 10
forkIO (reader a)
forkIO (writer a)
-- and you should do something to wait for reader and writer to finish