Это грубый код, использующий транзакционные переменные (то есть программную транзакционную память).Вы можете использовать IORef, MVar или множество других конструкций.
main = do
recvFunc <- initNetwork
cntTV <- newTVarIO 0
forkIO $ threadA recvFunc cntTV
runGUI cntTV 0
Выше, чем запустить программу, инициализируйте сеть и общую переменную cntTV
threadA recvCntFromNetwork cntTVar = forever $ do
cnt <- recvCntFromNetwork
atomically (writeTVar cntTVar cnt)
threadA
получает данные из сети и записывает новое значение счетчика в общую переменную.
runGUI cntTVar currentCnt = do
counter <- initGUI
cnt <- atomically $ do
cnt <- readTVar cntTVar
if (cnt == currentCnt)
then retry
else return cnt
updateGUICounter counter cnt
runGUI cntTVar cnt
runGUI
читает общую переменную и, если есть изменения, обновляет счетчик графического интерфейса.К вашему сведению, поток runGUI не будет активирован retry
до тех пор, пока cntTVar
не будет изменен, так что это не цикл опроса ЦП.
В этом коде я предположил, что у вас есть функции с именем updateGUICounter
, initGUI
и initNetwork
.Я советую вам использовать Hoogle, чтобы найти расположение любых других функций, которые вы еще не знаете, и немного узнать о каждом модуле.