У меня есть программа, которая решает некоторые проблемы, и я решил, что хочу отслеживать в хорошем графическом интерфейсе, что он делает. Для GUI я выбрал Gtk
, что означает, что мне нужно запустить цикл mainGUI
в выделенном потоке, а остальная часть моей программы займет другой поток. Я думал, что связь между моей программой и другой нитью будет протекать в одном направлении, используя Chan
. Я также решил использовать FRP для обновления GUI по уведомлению от работника (логика исходной программы в отдельном потоке). Поэтому я попытался написать простой пример с резьбой, где один поток отправляет IO
действия в поток мониторинга, который выполняет действия (отображает их). Вот моя попытка:События от общего канала связи между потоками
import Control.Concurrent
import Control.Monad
import Reactive.Banana
import Reactive.Banana.Frameworks
main = do
c <- newChan
forkIO $ do
actuate <=< compile $ reactimate'
<=< changes
<=< fromPoll
$ readChan c
forever $ do
threadDelay 3000000
putStrLn "sending msg"
writeChan c $ putStrLn "receiving msg"
Это, очевидно, не работает (это только отпечатки sending msg
), иначе я бы здесь не было. Что я делаю не так? Мне нужно другое событие, которое время опроса? Как это сделать?
Я ожидал некоторого чередования копий текстов: sending msg
и receiving msg
.
Для уточнения я хочу, чтобы перейти от
main = do
c <- newChan
forkIO . forever . join . readChan $ c
forever $ do
threadDelay 3000000
putStrLn "sending msg"
writeChan c $ putStrLn "receiving msg"
, где каждое сообщение в c :: Chan (IO())
читается в потоке в явном виде (возможно блокирование), реактивной обработки сообщений, т.е. описывающей сеть событий/поведение, связанное с элементами GUI, а затем пусть поток выполняет цикл GUI. Сеть должна будет заботиться о значениях опроса в канале и событиях стрельбы.
Решение, которое я искал (или нечто подобное):
main = do
(msgHandler, msgFire) <- newAddHandler
forkIO $ do
actuate <=< compile $ do
eMsg <- fromAddHandler msgHandler
reactimate $ putStrLn <$> eMsg
forever $ do
threadDelay 3000000
putStrLn "sending msg"
msgFire "receiving msg"
Это может быть полезно: https://wiki.haskell.org/Haskell_for_multicores#Message_passing_channels – jkeuhlen
Спасибо, я больше озадачен с FRP части, а не каналы, хотя. – jakubdaniel